<!DOCTYPE html>
<html><head><meta charset="utf-8" content="text/html" http-equiv="Content-Type" /><meta content="A Clojure implementation of the Non-Axiomatic Reasoning System proposed by Pei Wang." name="description" /><style type="text/css">/**
 * SyntaxHighlighter
 * http://alexgorbatchev.com/SyntaxHighlighter
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
 *
 * @version
 * 3.0.83 (July 02 2010)
 * 
 * @copyright
 * Copyright (C) 2004-2010 Alex Gorbatchev.
 *
 * @license
 * Dual licensed under the MIT and GPL licenses.
 */
.syntaxhighlighter a,
.syntaxhighlighter div,
.syntaxhighlighter code,
.syntaxhighlighter table,
.syntaxhighlighter table td,
.syntaxhighlighter table tr,
.syntaxhighlighter table tbody,
.syntaxhighlighter table thead,
.syntaxhighlighter table caption,
.syntaxhighlighter textarea {
  -moz-border-radius: 0 0 0 0 !important;
  -webkit-border-radius: 0 0 0 0 !important;
  background: none !important;
  border: 0 !important;
  bottom: auto !important;
  float: none !important;
  height: auto !important;
  left: auto !important;
  line-height: 1.1em !important;
/*  margin: 0 !important; */
  outline: 0 !important;
  overflow: visible !important;
  padding: 0 !important;
  position: static !important;
  right: auto !important;
  text-align: left !important;
  top: auto !important;
  vertical-align: baseline !important;
  width: auto !important;
  box-sizing: content-box !important;
  font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
  font-weight: normal !important;
  font-style: normal !important;
  min-height: inherit !important;
  min-height: auto !important;
}

.syntaxhighlighter {
/*  width: 100% !important; */
  margin: 1em 0 1em 0 !important;
  position: relative !important;
  overflow: auto !important;
}
.syntaxhighlighter.source {
  overflow: hidden !important;
}
.syntaxhighlighter .bold {
  font-weight: bold !important;
}
.syntaxhighlighter .italic {
  font-style: italic !important;
}
.syntaxhighlighter .line {
  white-space: pre !important;
}
.syntaxhighlighter table {
/*    width: 100% !important;*/
}
.syntaxhighlighter table caption {
  text-align: left !important;
  padding: .5em 0 0.5em 1em !important;
}
.syntaxhighlighter table td.code {
  width: 100% !important;
}
.syntaxhighlighter table td.code .container {
  position: relative !important;
}
.syntaxhighlighter table td.code .container textarea {
  box-sizing: border-box !important;
  position: absolute !important;
  left: 0 !important;
  top: 0 !important;
  width: 100% !important;
  height: 100% !important;
  border: none !important;
  background: white !important;
  padding-left: 1em !important;
  overflow: hidden !important;
  white-space: pre !important;
}
.syntaxhighlighter table td.gutter .line {
  text-align: right !important;
  padding: 0 0.5em 0 1em !important;
}
.syntaxhighlighter table td.code .line {
  padding: 0 1em !important;
}
.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {
  padding-left: 0em !important;
}
.syntaxhighlighter.show {
  display: block !important;
}
.syntaxhighlighter.collapsed table {
  display: none !important;
}
.syntaxhighlighter.collapsed .toolbar {
    display: none;
/*  padding: 0.1em 0.8em 0em 0.8em !important;
  font-size: 1em !important;
  position: static !important;
  width: auto !important;
  height: auto !important;*/
}
.syntaxhighlighter.collapsed .toolbar span {
  display: inline !important;
  margin-right: 1em !important;
}
.syntaxhighlighter.collapsed .toolbar span a {
  padding: 0 !important;
  display: none !important;
}
.syntaxhighlighter.collapsed .toolbar span a.expandSource {
  display: inline !important;
}
.syntaxhighlighter .toolbar {
    display: none;
/*  position: absolute !important;
  right: 1px !important;
  top: 1px !important;
  width: 11px !important;
  height: 11px !important;
  font-size: 10px !important;
  z-index: 10 !important;*/
}
.syntaxhighlighter .toolbar span.title {
  display: inline !important;
}
.syntaxhighlighter .toolbar a {
  display: block !important;
  text-align: center !important;
  text-decoration: none !important;
  padding-top: 1px !important;
}
.syntaxhighlighter .toolbar a.expandSource {
  display: none !important;
}
.syntaxhighlighter.ie {
  font-size: .9em !important;
  padding: 1px 0 1px 0 !important;
}
.syntaxhighlighter.ie .toolbar {
  line-height: 8px !important;
}
.syntaxhighlighter.ie .toolbar a {
  padding-top: 0px !important;
}
.syntaxhighlighter.printing .line.alt1 .content,
.syntaxhighlighter.printing .line.alt2 .content,
.syntaxhighlighter.printing .line.highlighted .number,
.syntaxhighlighter.printing .line.highlighted.alt1 .content,
.syntaxhighlighter.printing .line.highlighted.alt2 .content {
  background: none !important;
}
.syntaxhighlighter.printing .line .number {
  color: #bbbbbb !important;
}
.syntaxhighlighter.printing .line .content {
  color: black !important;
}
.syntaxhighlighter.printing .toolbar {
  display: none !important;
}
.syntaxhighlighter.printing a {
  text-decoration: none !important;
}
.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {
  color: black !important;
}
.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {
  color: #008200 !important;
}
.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {
  color: blue !important;
}
.syntaxhighlighter.printing .keyword {
  color: #006699 !important;
  font-weight: bold !important;
}
.syntaxhighlighter.printing .preprocessor {
  color: gray !important;
}
.syntaxhighlighter.printing .variable {
  color: #aa7700 !important;
}
.syntaxhighlighter.printing .value {
  color: #009900 !important;
}
.syntaxhighlighter.printing .functions {
  color: #ff1493 !important;
}
.syntaxhighlighter.printing .constants {
  color: #0066cc !important;
}
.syntaxhighlighter.printing .script {
  font-weight: bold !important;
}
.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {
  color: gray !important;
}
.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {
  color: #ff1493 !important;
}
.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {
  color: red !important;
}
.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {
  color: black !important;
}
</style><style type="text/css">.syntaxhighlighter{overflow:hidden !important;}</style><style type="text/css">/**
 * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
 *
 * @version
 * 3.0.83 (July 02 2010)
 * 
 * @copyright
 * Copyright (C) 2004-2010 Alex Gorbatchev.
 *
 * @license
 * Dual licensed under the MIT and GPL licenses.
 */
.syntaxhighlighter {
  background-color: transparent !important;
}
.syntaxhighlighter .line.alt1 {
  background-color: transparent !important;
}
.syntaxhighlighter .line.alt2 {
  background-color: transparent !important;
}
.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
  background-color: #c3defe !important;
}
.syntaxhighlighter .line.highlighted.number {
  color: white !important;
}
.syntaxhighlighter table caption {
  color: black !important;
}
.syntaxhighlighter .gutter {
  color: #787878 !important;
}
.syntaxhighlighter .gutter .line {
  border-right: 3px solid #d4d0c8 !important;
}
.syntaxhighlighter .gutter .line.highlighted {
  background-color: #d4d0c8 !important;
  color: white !important;
}
.syntaxhighlighter.printing .line .content {
  border: none !important;
}
.syntaxhighlighter.collapsed {
  overflow: visible !important;
}
.syntaxhighlighter.collapsed .toolbar {
  color: #3f5fbf !important;
  background: white !important;
  border: 1px solid #d4d0c8 !important;
}
.syntaxhighlighter.collapsed .toolbar a {
  color: #3f5fbf !important;
}
.syntaxhighlighter.collapsed .toolbar a:hover {
  color: #aa7700 !important;
}
.syntaxhighlighter .toolbar {
  color: #a0a0a0 !important;
  background: #d4d0c8 !important;
  border: none !important;
}
.syntaxhighlighter .toolbar a {
  color: #a0a0a0 !important;
}
.syntaxhighlighter .toolbar a:hover {
  color: red !important;
}
.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
  color: black !important;
}
.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
  color: #3f5fbf !important;
}
.syntaxhighlighter .string, .syntaxhighlighter .string a {
  color: #2a00ff !important;
}
.syntaxhighlighter .keyword {
  color: #7f0055 !important;
}
.syntaxhighlighter .preprocessor {
  color: #646464 !important;
}
.syntaxhighlighter .variable {
  color: #aa7700 !important;
}
.syntaxhighlighter .value {
  color: #009900 !important;
}
.syntaxhighlighter .functions {
  color: #ff1493 !important;
}
.syntaxhighlighter .constants {
  color: #0066cc !important;
}
.syntaxhighlighter .script {
  font-weight: bold !important;
  color: #7f0055 !important;
  background-color: none !important;
}
.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
  color: gray !important;
}
.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
  color: #ff1493 !important;
}
.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
  color: red !important;
}

.syntaxhighlighter .xml .keyword {
  color: #3f7f7f !important;
  font-weight: normal !important;
}
.syntaxhighlighter .xml .color1, .syntaxhighlighter .xml .color1 a {
  color: #7f007f !important;
}
.syntaxhighlighter .xml .string {
  font-style: italic !important;
  color: #2a00ff !important;
}

.clojure.syntaxhighlighter .invalid { 
   background-color: #FAA !important;
}

.clojure.syntaxhighlighter .quoted {      
    font-style: italic !important;
}

.syntaxhighlighter .clojure.variable,
.syntaxhighlighter .clojure.symbol,
.syntaxhighlighter .clojure.value
{
    color: #006060 !important;
}

.syntaxhighlighter .clojure.string {
    color: #55B !important;
}

.syntaxhighlighter .clojure.functions {
    color: black !important;
}

.syntaxhighlighter .clojure.color1 {
    color: #666 !important;
}

.syntaxhighlighter .clojure.color3 {
    color: #900 !important;
}

.syntaxhighlighter .clojure.constants {
    color: #1A734D !important;
}

</style><style type="text/css">html{margin:0;padding:0;}h1{margin:0;padding:0;}h2{margin:0;padding:0;}h3{margin:0;padding:0;}h4{margin:0;padding:0;}a{color:#261A3B;}a:visited{color:#261A3B;}</style><style type="text/css">.header{margin-top:30px;}h1.project-name{font-size:34px;display:inline;}h2.project-version{font-size:18px;margin-top:0;display:inline;margin-left:10px;}.toc-link{font-size:12px;margin-left:10px;color:#252519;text-decoration:none;}.toc-link:hover{color:#5050A6;}.toc h1{font-size:34px;margin:0;}.docs-header{border-bottom:dotted #aaa 1px;padding-bottom:10px;margin-bottom:25px;}.toc h1{font-size:24px;}.toc{border-bottom:solid #bbb 1px;margin-bottom:40px;}.toc ul{margin-left:20px;padding-left:0px;padding-top:0;margin-top:0;}.toc li{list-style-type:none;padding-left:0;}.dependencies{}.dependencies table{font-size:16px;width:99.99%;border:none;margin-left:20px;}.dependencies td{padding-right:20px;;white-space:nowrap;}.dependencies .dotted{width:99%;}.dependencies .dotted hr{border-right:none;color:transparent;background-color:transparent;noshade:noshade;border-left:none;border-top:none;margin-bottom:-6px;height:0;border-bottom:dotted #bbb 1px;}.dependencies .dep-version{text-align:right;}.plugins ul{margin-left:20px;padding-left:0px;padding-top:0;margin-top:0;}.plugins li{list-style-type:none;padding-left:0;}.header p{margin-left:20px;}</style><style type="text/css">#floating-toc{position:fixed;top:10px;right:20px;height:20px;overflow:hidden;text-align:right;}#floating-toc li{list-style-type:none;margin:0;padding:0;}</style><style type="text/css">body{margin:0;padding:0;font-family:'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;;font-size:16px;color:#252519;background-color:#F5F5FF;}h1{font-size:20px;margin-top:0;}h2{font-size:18px;}h3{font-size:16px;}a.anchor{text-decoration:none;color:#252519;}a.anchor:hover{color:#5050A6;}table{border-spacing:0;border-bottom:solid #ddd 1px;;margin-bottom:10px;}code{display:inline;}p{margin-top:8px;}tr{margin:0px;padding:0px;}td.docs{width:410px;max-width:410px;vertical-align:top;margin:0px;padding-left:55px;padding-right:20px;border:none;background-color:#FFF;}td.docs pre{font-size:12px;overflow:hidden;}td.codes{vertical-align:top;font-size:10pt;overflow:hidden;background-color:#F5F5FF;width:55%;border-left:solid #E5E5EE 1px;padding-left:20px;border:none;margin:0px;}td.spacer{padding-bottom:40px;}pre code{display:block;padding:4px;}code{background-color:ghostWhite;border:solid #DEDEDE 1px;padding-left:3px;padding-right:3px;font-size:14px;}.syntaxhighlighter code{font-size:13px;}.footer{text-align:center;}</style><script type="text/javascript">/*! jQuery v1.7.1 jquery.com | jquery.org/license */
(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
</script><script type="text/javascript">//XRegExp 1.5.0 <xregexp.com> MIT License
var XRegExp;if(XRegExp){throw Error("can't load XRegExp twice in the same frame")}(function(){XRegExp=function(w,r){var q=[],u=XRegExp.OUTSIDE_CLASS,x=0,p,s,v,t,y;if(XRegExp.isRegExp(w)){if(r!==undefined){throw TypeError("can't supply flags when constructing one RegExp from another")}return j(w)}if(g){throw Error("can't call the XRegExp constructor within token definition functions")}r=r||"";p={hasNamedCapture:false,captureNames:[],hasFlag:function(z){return r.indexOf(z)>-1},setFlag:function(z){r+=z}};while(x<w.length){s=o(w,x,u,p);if(s){q.push(s.output);x+=(s.match[0].length||1)}else{if(v=m.exec.call(i[u],w.slice(x))){q.push(v[0]);x+=v[0].length}else{t=w.charAt(x);if(t==="["){u=XRegExp.INSIDE_CLASS}else{if(t==="]"){u=XRegExp.OUTSIDE_CLASS}}q.push(t);x++}}}y=RegExp(q.join(""),m.replace.call(r,h,""));y._xregexp={source:w,captureNames:p.hasNamedCapture?p.captureNames:null};return y};XRegExp.version="1.5.0";XRegExp.INSIDE_CLASS=1;XRegExp.OUTSIDE_CLASS=2;var c=/\$(?:(\d\d?|[$&`'])|{([$\w]+)})/g,h=/[^gimy]+|([\s\S])(?=[\s\S]*\1)/g,n=/^(?:[?*+]|{\d+(?:,\d*)?})\??/,g=false,k=[],m={exec:RegExp.prototype.exec,test:RegExp.prototype.test,match:String.prototype.match,replace:String.prototype.replace,split:String.prototype.split},a=m.exec.call(/()??/,"")[1]===undefined,e=function(){var p=/^/g;m.test.call(p,"");return !p.lastIndex}(),f=function(){var p=/x/g;m.replace.call("x",p,"");return !p.lastIndex}(),b=RegExp.prototype.sticky!==undefined,i={};i[XRegExp.INSIDE_CLASS]=/^(?:\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S]))/;i[XRegExp.OUTSIDE_CLASS]=/^(?:\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\d*|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S])|\(\?[:=!]|[?*+]\?|{\d+(?:,\d*)?}\??)/;XRegExp.addToken=function(s,r,q,p){k.push({pattern:j(s,"g"+(b?"y":"")),handler:r,scope:q||XRegExp.OUTSIDE_CLASS,trigger:p||null})};XRegExp.cache=function(r,p){var q=r+"/"+(p||"");return XRegExp.cache[q]||(XRegExp.cache[q]=XRegExp(r,p))};XRegExp.copyAsGlobal=function(p){return j(p,"g")};XRegExp.escape=function(p){return p.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")};XRegExp.execAt=function(s,r,t,q){r=j(r,"g"+((q&&b)?"y":""));r.lastIndex=t=t||0;var p=r.exec(s);if(q){return(p&&p.index===t)?p:null}else{return p}};XRegExp.freezeTokens=function(){XRegExp.addToken=function(){throw Error("can't run addToken after freezeTokens")}};XRegExp.isRegExp=function(p){return Object.prototype.toString.call(p)==="[object RegExp]"};XRegExp.iterate=function(u,p,v,s){var t=j(p,"g"),r=-1,q;while(q=t.exec(u)){v.call(s,q,++r,u,t);if(t.lastIndex===q.index){t.lastIndex++}}if(p.global){p.lastIndex=0}};XRegExp.matchChain=function(q,p){return function r(s,x){var v=p[x].regex?p[x]:{regex:p[x]},u=j(v.regex,"g"),w=[],t;for(t=0;t<s.length;t++){XRegExp.iterate(s[t],u,function(y){w.push(v.backref?(y[v.backref]||""):y[0])})}return((x===p.length-1)||!w.length)?w:r(w,x+1)}([q],0)};RegExp.prototype.apply=function(q,p){return this.exec(p[0])};RegExp.prototype.call=function(p,q){return this.exec(q)};RegExp.prototype.exec=function(t){var r=m.exec.apply(this,arguments),q,p;if(r){if(!a&&r.length>1&&l(r,"")>-1){p=RegExp(this.source,m.replace.call(d(this),"g",""));m.replace.call(t.slice(r.index),p,function(){for(var u=1;u<arguments.length-2;u++){if(arguments[u]===undefined){r[u]=undefined}}})}if(this._xregexp&&this._xregexp.captureNames){for(var s=1;s<r.length;s++){q=this._xregexp.captureNames[s-1];if(q){r[q]=r[s]}}}if(!e&&this.global&&!r[0].length&&(this.lastIndex>r.index)){this.lastIndex--}}return r};if(!e){RegExp.prototype.test=function(q){var p=m.exec.call(this,q);if(p&&this.global&&!p[0].length&&(this.lastIndex>p.index)){this.lastIndex--}return !!p}}String.prototype.match=function(q){if(!XRegExp.isRegExp(q)){q=RegExp(q)}if(q.global){var p=m.match.apply(this,arguments);q.lastIndex=0;return p}return q.exec(this)};String.prototype.replace=function(r,s){var t=XRegExp.isRegExp(r),q,p,u;if(t&&typeof s.valueOf()==="string"&&s.indexOf("${")===-1&&f){return m.replace.apply(this,arguments)}if(!t){r=r+""}else{if(r._xregexp){q=r._xregexp.captureNames}}if(typeof s==="function"){p=m.replace.call(this,r,function(){if(q){arguments[0]=new String(arguments[0]);for(var v=0;v<q.length;v++){if(q[v]){arguments[0][q[v]]=arguments[v+1]}}}if(t&&r.global){r.lastIndex=arguments[arguments.length-2]+arguments[0].length}return s.apply(null,arguments)})}else{u=this+"";p=m.replace.call(u,r,function(){var v=arguments;return m.replace.call(s,c,function(x,w,A){if(w){switch(w){case"$":return"$";case"&":return v[0];case"`":return v[v.length-1].slice(0,v[v.length-2]);case"'":return v[v.length-1].slice(v[v.length-2]+v[0].length);default:var y="";w=+w;if(!w){return x}while(w>v.length-3){y=String.prototype.slice.call(w,-1)+y;w=Math.floor(w/10)}return(w?v[w]||"":"$")+y}}else{var z=+A;if(z<=v.length-3){return v[z]}z=q?l(q,A):-1;return z>-1?v[z+1]:x}})})}if(t&&r.global){r.lastIndex=0}return p};String.prototype.split=function(u,p){if(!XRegExp.isRegExp(u)){return m.split.apply(this,arguments)}var w=this+"",r=[],v=0,t,q;if(p===undefined||+p<0){p=Infinity}else{p=Math.floor(+p);if(!p){return[]}}u=XRegExp.copyAsGlobal(u);while(t=u.exec(w)){if(u.lastIndex>v){r.push(w.slice(v,t.index));if(t.length>1&&t.index<w.length){Array.prototype.push.apply(r,t.slice(1))}q=t[0].length;v=u.lastIndex;if(r.length>=p){break}}if(u.lastIndex===t.index){u.lastIndex++}}if(v===w.length){if(!m.test.call(u,"")||q){r.push("")}}else{r.push(w.slice(v))}return r.length>p?r.slice(0,p):r};function j(r,q){if(!XRegExp.isRegExp(r)){throw TypeError("type RegExp expected")}var p=r._xregexp;r=XRegExp(r.source,d(r)+(q||""));if(p){r._xregexp={source:p.source,captureNames:p.captureNames?p.captureNames.slice(0):null}}return r}function d(p){return(p.global?"g":"")+(p.ignoreCase?"i":"")+(p.multiline?"m":"")+(p.extended?"x":"")+(p.sticky?"y":"")}function o(v,u,w,p){var r=k.length,y,s,x;g=true;try{while(r--){x=k[r];if((w&x.scope)&&(!x.trigger||x.trigger.call(p))){x.pattern.lastIndex=u;s=x.pattern.exec(v);if(s&&s.index===u){y={output:x.handler.call(p,s,w),match:s};break}}}}catch(q){throw q}finally{g=false}return y}function l(s,q,r){if(Array.prototype.indexOf){return s.indexOf(q,r)}for(var p=r||0;p<s.length;p++){if(s[p]===q){return p}}return -1}XRegExp.addToken(/\(\?#[^)]*\)/,function(p){return m.test.call(n,p.input.slice(p.index+p[0].length))?"":"(?:)"});XRegExp.addToken(/\((?!\?)/,function(){this.captureNames.push(null);return"("});XRegExp.addToken(/\(\?<([$\w]+)>/,function(p){this.captureNames.push(p[1]);this.hasNamedCapture=true;return"("});XRegExp.addToken(/\\k<([\w$]+)>/,function(q){var p=l(this.captureNames,q[1]);return p>-1?"\\"+(p+1)+(isNaN(q.input.charAt(q.index+q[0].length))?"":"(?:)"):q[0]});XRegExp.addToken(/\[\^?]/,function(p){return p[0]==="[]"?"\\b\\B":"[\\s\\S]"});XRegExp.addToken(/^\(\?([imsx]+)\)/,function(p){this.setFlag(p[1]);return""});XRegExp.addToken(/(?:\s+|#.*)+/,function(p){return m.test.call(n,p.input.slice(p.index+p[0].length))?"":"(?:)"},XRegExp.OUTSIDE_CLASS,function(){return this.hasFlag("x")});XRegExp.addToken(/\./,function(){return"[\\s\\S]"},XRegExp.OUTSIDE_CLASS,function(){return this.hasFlag("s")})})();
</script><script type="text/javascript">/**
 * SyntaxHighlighter
 * http://alexgorbatchev.com/SyntaxHighlighter
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
 *
 * @version
 * 3.0.83 (July 02 2010)
 * 
 * @copyright
 * Copyright (C) 2004-2010 Alex Gorbatchev.
 *
 * @license
 * Dual licensed under the MIT and GPL licenses.
 */
//
// Begin anonymous function. This is used to contain local scope variables without polutting global scope.
//
var SyntaxHighlighter = function() { 

// CommonJS
if (typeof(require) != 'undefined' && typeof(XRegExp) == 'undefined')
{
	XRegExp = require('XRegExp').XRegExp;
}

// Shortcut object which will be assigned to the SyntaxHighlighter variable.
// This is a shorthand for local reference in order to avoid long namespace 
// references to SyntaxHighlighter.whatever...
var sh = {
	defaults : {
		/** Additional CSS class names to be added to highlighter elements. */
		'class-name' : '',
		
		/** First line number. */
		'first-line' : 1,
		
		/**
		 * Pads line numbers. Possible values are:
		 *
		 *   false - don't pad line numbers.
		 *   true  - automaticaly pad numbers with minimum required number of leading zeroes.
		 *   [int] - length up to which pad line numbers.
		 */
		'pad-line-numbers' : false,
		
		/** Lines to highlight. */
		'highlight' : null,
		
		/** Title to be displayed above the code block. */
		'title' : null,
		
		/** Enables or disables smart tabs. */
		'smart-tabs' : true,
		
		/** Gets or sets tab size. */
		'tab-size' : 4,
		
		/** Enables or disables gutter. */
		'gutter' : true,
		
		/** Enables or disables toolbar. */
		'toolbar' : true,
		
		/** Enables quick code copy and paste from double click. */
		'quick-code' : true,
		
		/** Forces code view to be collapsed. */
		'collapse' : false,
		
		/** Enables or disables automatic links. */
		'auto-links' : true,
		
		/** Gets or sets light mode. Equavalent to turning off gutter and toolbar. */
		'light' : false,
		
		'html-script' : false
	},
	
	config : {
		space : '&nbsp;',
		
		/** Enables use of <SCRIPT type="syntaxhighlighter" /> tags. */
		useScriptTags : true,
		
		/** Blogger mode flag. */
		bloggerMode : false,
		
		stripBrs : false,
		
		/** Name of the tag that SyntaxHighlighter will automatically look for. */
		tagName : 'pre',
		
		strings : {
			expandSource : 'expand source',
			help : '?',
			alert: 'SyntaxHighlighter\n\n',
			noBrush : 'Can\'t find brush for: ',
			brushNotHtmlScript : 'Brush wasn\'t configured for html-script option: ',
			
			// this is populated by the build script
			aboutDialog : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>About SyntaxHighlighter</title></head><body style="font-family:Geneva,Arial,Helvetica,sans-serif;background-color:#fff;color:#000;font-size:1em;text-align:center;"><div style="text-align:center;margin-top:1.5em;"><div style="font-size:xx-large;">SyntaxHighlighter</div><div style="font-size:.75em;margin-bottom:3em;"><div>version 3.0.83 (July 02 2010)</div><div><a href="http://alexgorbatchev.com/SyntaxHighlighter" target="_blank" style="color:#005896">http://alexgorbatchev.com/SyntaxHighlighter</a></div><div>JavaScript code syntax highlighter.</div><div>Copyright 2004-2010 Alex Gorbatchev.</div></div><div>If you like this script, please <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=2930402" style="color:#005896">donate</a> to <br/>keep development active!</div></div></body></html>'
		}
	},
	
	/** Internal 'global' variables. */
	vars : {
		discoveredBrushes : null,
		highlighters : {}
	},
	
	/** This object is populated by user included external brush files. */
	brushes : {},

	/** Common regular expressions. */
	regexLib : {
		multiLineCComments			: /\/\*[\s\S]*?\*\//gm,
		singleLineCComments			: /\/\/.*$/gm,
		singleLinePerlComments		: /#.*$/gm,
		doubleQuotedString			: /"([^\\"\n]|\\.)*"/g,
		singleQuotedString			: /'([^\\'\n]|\\.)*'/g,
		multiLineDoubleQuotedString	: new XRegExp('"([^\\\\"]|\\\\.)*"', 'gs'),
		multiLineSingleQuotedString	: new XRegExp("'([^\\\\']|\\\\.)*'", 'gs'),
		xmlComments					: /(&lt;|<)!--[\s\S]*?--(&gt;|>)/gm,
		url							: /\w+:\/\/[\w-.\/?%&=:@;]*/g,
		
		/** <?= ?> tags. */
		phpScriptTags 				: { left: /(&lt;|<)\?=?/g, right: /\?(&gt;|>)/g },
		
		/** <%= %> tags. */
		aspScriptTags				: { left: /(&lt;|<)%=?/g, right: /%(&gt;|>)/g },
		
		scriptScriptTags			: { left: /(&lt;|<)\s*script.*?(&gt;|>)/gi, right: /(&lt;|<)\/\s*script\s*(&gt;|>)/gi }
	},

	toolbar: {
		/**
		 * Generates HTML markup for the toolbar.
		 * @param {Highlighter} highlighter Highlighter instance.
		 * @return {String} Returns HTML markup.
		 */
		getHtml: function(highlighter)
		{
			var html = '<div class="toolbar">',
				items = sh.toolbar.items,
				list = items.list
				;
			
			function defaultGetHtml(highlighter, name)
			{
				return sh.toolbar.getButtonHtml(highlighter, name, sh.config.strings[name]);
			};
			
			for (var i = 0; i < list.length; i++)
				html += (items[list[i]].getHtml || defaultGetHtml)(highlighter, list[i]);
			
			html += '</div>';
			
			return html;
		},
		
		/**
		 * Generates HTML markup for a regular button in the toolbar.
		 * @param {Highlighter} highlighter Highlighter instance.
		 * @param {String} commandName		Command name that would be executed.
		 * @param {String} label			Label text to display.
		 * @return {String}					Returns HTML markup.
		 */
		getButtonHtml: function(highlighter, commandName, label)
		{
			return '<span><a href="#" class="toolbar_item'
				+ ' command_' + commandName
				+ ' ' + commandName
				+ '">' + label + '</a></span>'
				;
		},
		
		/**
		 * Event handler for a toolbar anchor.
		 */
		handler: function(e)
		{
			var target = e.target,
				className = target.className || ''
				;

			function getValue(name)
			{
				var r = new RegExp(name + '_(\\w+)'),
					match = r.exec(className)
					;

				return match ? match[1] : null;
			};
			
			var highlighter = getHighlighterById(findParentElement(target, '.syntaxhighlighter').id),
				commandName = getValue('command')
				;
			
			// execute the toolbar command
			if (highlighter && commandName)
				sh.toolbar.items[commandName].execute(highlighter);

			// disable default A click behaviour
			e.preventDefault();
		},
		
		/** Collection of toolbar items. */
		items : {
			// Ordered lis of items in the toolbar. Can't expect `for (var n in items)` to be consistent.
			list: ['expandSource', 'help'],

			expandSource: {
				getHtml: function(highlighter)
				{
					if (highlighter.getParam('collapse') != true)
						return '';
						
					var title = highlighter.getParam('title');
					return sh.toolbar.getButtonHtml(highlighter, 'expandSource', title ? title : sh.config.strings.expandSource);
				},
			
				execute: function(highlighter)
				{
					var div = getHighlighterDivById(highlighter.id);
					removeClass(div, 'collapsed');
				}
			},

			/** Command to display the about dialog window. */
			help: {
				execute: function(highlighter)
				{	
					var wnd = popup('', '_blank', 500, 250, 'scrollbars=0'),
						doc = wnd.document
						;
					
					doc.write(sh.config.strings.aboutDialog);
					doc.close();
					wnd.focus();
				}
			}
		}
	},

	/**
	 * Finds all elements on the page which should be processes by SyntaxHighlighter.
	 *
	 * @param {Object} globalParams		Optional parameters which override element's 
	 * 									parameters. Only used if element is specified.
	 * 
	 * @param {Object} element	Optional element to highlight. If none is
	 * 							provided, all elements in the current document 
	 * 							are returned which qualify.
	 *
	 * @return {Array}	Returns list of <code>{ target: DOMElement, params: Object }</code> objects.
	 */
	findElements: function(globalParams, element)
	{
		var elements = element ? [element] : toArray(document.getElementsByTagName(sh.config.tagName)), 
			conf = sh.config,
			result = []
			;

		// support for <SCRIPT TYPE="syntaxhighlighter" /> feature
		if (conf.useScriptTags)
			elements = elements.concat(getSyntaxHighlighterScriptTags());

		if (elements.length === 0) 
			return result;
	
		for (var i = 0; i < elements.length; i++) 
		{
			var item = {
				target: elements[i], 
				// local params take precedence over globals
				params: merge(globalParams, parseParams(elements[i].className))
			};

			if (item.params['brush'] == null)
				continue;
				
			result.push(item);
		}
		
		return result;
	},

	/**
	 * Shorthand to highlight all elements on the page that are marked as 
	 * SyntaxHighlighter source code.
	 * 
	 * @param {Object} globalParams		Optional parameters which override element's 
	 * 									parameters. Only used if element is specified.
	 * 
	 * @param {Object} element	Optional element to highlight. If none is
	 * 							provided, all elements in the current document 
	 * 							are highlighted.
	 */ 
	highlight: function(globalParams, element)
	{
		var elements = this.findElements(globalParams, element),
			propertyName = 'innerHTML', 
			highlighter = null,
			conf = sh.config
			;

		if (elements.length === 0) 
			return;
	
		for (var i = 0; i < elements.length; i++) 
		{
			var element = elements[i],
				target = element.target,
				params = element.params,
				brushName = params.brush,
				code
				;

			if (brushName == null)
				continue;

			// Instantiate a brush
			if (params['html-script'] == 'true' || sh.defaults['html-script'] == true) 
			{
				highlighter = new sh.HtmlScript(brushName);
				brushName = 'htmlscript';
			}
			else
			{
				var brush = findBrush(brushName);
				
				if (brush)
					highlighter = new brush();
				else
					continue;
			}
			
			code = target[propertyName];
			
			// remove CDATA from <SCRIPT/> tags if it's present
			if (conf.useScriptTags)
				code = stripCData(code);
				
			// Inject title if the attribute is present
			if ((target.title || '') != '')
				params.title = target.title;
				
			params['brush'] = brushName;
			highlighter.init(params);
			element = highlighter.getDiv(code);
			
			// carry over ID
			if ((target.id || '') != '')
				element.id = target.id;
			
			target.parentNode.replaceChild(element, target);
		}
	},

	/**
	 * Main entry point for the SyntaxHighlighter.
	 * @param {Object} params Optional params to apply to all highlighted elements.
	 */
	all: function(params)
	{
		attachEvent(
			window,
			'load',
			function() { sh.highlight(params); }
		);
	}
}; // end of sh

sh['all']			= sh.all;
sh['highlight']		= sh.highlight;

/**
 * Checks if target DOM elements has specified CSS class.
 * @param {DOMElement} target Target DOM element to check.
 * @param {String} className Name of the CSS class to check for.
 * @return {Boolean} Returns true if class name is present, false otherwise.
 */
function hasClass(target, className)
{
	return target.className.indexOf(className) != -1;
};

/**
 * Adds CSS class name to the target DOM element.
 * @param {DOMElement} target Target DOM element.
 * @param {String} className New CSS class to add.
 */
function addClass(target, className)
{
	if (!hasClass(target, className))
		target.className += ' ' + className;
};

/**
 * Removes CSS class name from the target DOM element.
 * @param {DOMElement} target Target DOM element.
 * @param {String} className CSS class to remove.
 */
function removeClass(target, className)
{
	target.className = target.className.replace(className, '');
};

/**
 * Converts the source to array object. Mostly used for function arguments and 
 * lists returned by getElementsByTagName() which aren't Array objects.
 * @param {List} source Source list.
 * @return {Array} Returns array.
 */
function toArray(source)
{
	var result = [];
	
	for (var i = 0; i < source.length; i++) 
		result.push(source[i]);
		
	return result;
};

/**
 * Splits block of text into lines.
 * @param {String} block Block of text.
 * @return {Array} Returns array of lines.
 */
function splitLines(block)
{
	return block.split('\n');
}

/**
 * Generates HTML ID for the highlighter.
 * @param {String} highlighterId Highlighter ID.
 * @return {String} Returns HTML ID.
 */
function getHighlighterId(id)
{
	var prefix = 'highlighter_';
	return id.indexOf(prefix) == 0 ? id : prefix + id;
};

/**
 * Finds Highlighter instance by ID.
 * @param {String} highlighterId Highlighter ID.
 * @return {Highlighter} Returns instance of the highlighter.
 */
function getHighlighterById(id)
{
	return sh.vars.highlighters[getHighlighterId(id)];
};

/**
 * Finds highlighter's DIV container.
 * @param {String} highlighterId Highlighter ID.
 * @return {Element} Returns highlighter's DIV element.
 */
function getHighlighterDivById(id)
{
	return document.getElementById(getHighlighterId(id));
};

/**
 * Stores highlighter so that getHighlighterById() can do its thing. Each
 * highlighter must call this method to preserve itself.
 * @param {Highilghter} highlighter Highlighter instance.
 */
function storeHighlighter(highlighter)
{
	sh.vars.highlighters[getHighlighterId(highlighter.id)] = highlighter;
};

/**
 * Looks for a child or parent node which has specified classname.
 * Equivalent to jQuery's $(container).find(".className")
 * @param {Element} target Target element.
 * @param {String} search Class name or node name to look for.
 * @param {Boolean} reverse If set to true, will go up the node tree instead of down.
 * @return {Element} Returns found child or parent element on null.
 */
function findElement(target, search, reverse /* optional */)
{
	if (target == null)
		return null;
		
	var nodes			= reverse != true ? target.childNodes : [ target.parentNode ],
		propertyToFind	= { '#' : 'id', '.' : 'className' }[search.substr(0, 1)] || 'nodeName',
		expectedValue,
		found
		;

	expectedValue = propertyToFind != 'nodeName'
		? search.substr(1)
		: search.toUpperCase()
		;
		
	// main return of the found node
	if ((target[propertyToFind] || '').indexOf(expectedValue) != -1)
		return target;
	
	for (var i = 0; nodes && i < nodes.length && found == null; i++)
		found = findElement(nodes[i], search, reverse);
	
	return found;
};

/**
 * Looks for a parent node which has specified classname.
 * This is an alias to <code>findElement(container, className, true)</code>.
 * @param {Element} target Target element.
 * @param {String} className Class name to look for.
 * @return {Element} Returns found parent element on null.
 */
function findParentElement(target, className)
{
	return findElement(target, className, true);
};

/**
 * Finds an index of element in the array.
 * @ignore
 * @param {Object} searchElement
 * @param {Number} fromIndex
 * @return {Number} Returns index of element if found; -1 otherwise.
 */
function indexOf(array, searchElement, fromIndex)
{
	fromIndex = Math.max(fromIndex || 0, 0);

	for (var i = fromIndex; i < array.length; i++)
		if(array[i] == searchElement)
			return i;
	
	return -1;
};

/**
 * Generates a unique element ID.
 */
function guid(prefix)
{
	return (prefix || '') + Math.round(Math.random() * 1000000).toString();
};

/**
 * Merges two objects. Values from obj2 override values in obj1.
 * Function is NOT recursive and works only for one dimensional objects.
 * @param {Object} obj1 First object.
 * @param {Object} obj2 Second object.
 * @return {Object} Returns combination of both objects.
 */
function merge(obj1, obj2)
{
	var result = {}, name;

	for (name in obj1) 
		result[name] = obj1[name];
	
	for (name in obj2) 
		result[name] = obj2[name];
		
	return result;
};

/**
 * Attempts to convert string to boolean.
 * @param {String} value Input string.
 * @return {Boolean} Returns true if input was "true", false if input was "false" and value otherwise.
 */
function toBoolean(value)
{
	var result = { "true" : true, "false" : false }[value];
	return result == null ? value : result;
};

/**
 * Opens up a centered popup window.
 * @param {String} url		URL to open in the window.
 * @param {String} name		Popup name.
 * @param {int} width		Popup width.
 * @param {int} height		Popup height.
 * @param {String} options	window.open() options.
 * @return {Window}			Returns window instance.
 */
function popup(url, name, width, height, options)
{
	var x = (screen.width - width) / 2,
		y = (screen.height - height) / 2
		;
		
	options +=	', left=' + x + 
				', top=' + y +
				', width=' + width +
				', height=' + height
		;
	options = options.replace(/^,/, '');

	var win = window.open(url, name, options);
	win.focus();
	return win;
};

/**
 * Adds event handler to the target object.
 * @param {Object} obj		Target object.
 * @param {String} type		Name of the event.
 * @param {Function} func	Handling function.
 */
function attachEvent(obj, type, func, scope)
{
	function handler(e)
	{
		e = e || window.event;
		
		if (!e.target)
		{
			e.target = e.srcElement;
			e.preventDefault = function()
			{
				this.returnValue = false;
			};
		}
			
		func.call(scope || window, e);
	};
	
	if (obj.attachEvent) 
	{
		obj.attachEvent('on' + type, handler);
	}
	else 
	{
		obj.addEventListener(type, handler, false);
	}
};

/**
 * Displays an alert.
 * @param {String} str String to display.
 */
function alert(str)
{
	window.alert(sh.config.strings.alert + str);
};

/**
 * Finds a brush by its alias.
 *
 * @param {String} alias		Brush alias.
 * @param {Boolean} showAlert	Suppresses the alert if false.
 * @return {Brush}				Returns bursh constructor if found, null otherwise.
 */
function findBrush(alias, showAlert)
{
	var brushes = sh.vars.discoveredBrushes,
		result = null
		;
	
	if (brushes == null) 
	{
		brushes = {};
		
		// Find all brushes
		for (var brush in sh.brushes) 
		{
			var info = sh.brushes[brush],
				aliases = info.aliases
				;
			
			if (aliases == null) 
				continue;
			
			// keep the brush name
			info.brushName = brush.toLowerCase();
			
			for (var i = 0; i < aliases.length; i++) 
				brushes[aliases[i]] = brush;
		}
		
		sh.vars.discoveredBrushes = brushes;
	}
	
	result = sh.brushes[brushes[alias]];

	if (result == null && showAlert != false)
		alert(sh.config.strings.noBrush + alias);
	
	return result;
};

/**
 * Executes a callback on each line and replaces each line with result from the callback.
 * @param {Object} str			Input string.
 * @param {Object} callback		Callback function taking one string argument and returning a string.
 */
function eachLine(str, callback)
{
	var lines = splitLines(str);
	
	for (var i = 0; i < lines.length; i++)
		lines[i] = callback(lines[i], i);
		
	return lines.join('\n');
};

/**
 * This is a special trim which only removes first and last empty lines
 * and doesn't affect valid leading space on the first line.
 * 
 * @param {String} str   Input string
 * @return {String}      Returns string without empty first and last lines.
 */
function trimFirstAndLastLines(str)
{
	return str.replace(/^[ ]*[\n]+|[\n]*[ ]*$/g, '');
};

/**
 * Parses key/value pairs into hash object.
 * 
 * Understands the following formats:
 * - name: word;
 * - name: [word, word];
 * - name: "string";
 * - name: 'string';
 * 
 * For example:
 *   name1: value; name2: [value, value]; name3: 'value'
 *   
 * @param {String} str    Input string.
 * @return {Object}       Returns deserialized object.
 */
function parseParams(str)
{
	var match, 
		result = {},
		arrayRegex = new XRegExp("^\\[(?<values>(.*?))\\]$"),
		regex = new XRegExp(
			"(?<name>[\\w-]+)" +
			"\\s*:\\s*" +
			"(?<value>" +
				"[\\w-%#]+|" +		// word
				"\\[.*?\\]|" +		// [] array
				'".*?"|' +			// "" string
				"'.*?'" +			// '' string
			")\\s*;?",
			"g"
		)
		;

	while ((match = regex.exec(str)) != null) 
	{
		var value = match.value
			.replace(/^['"]|['"]$/g, '') // strip quotes from end of strings
			;
		
		// try to parse array value
		if (value != null && arrayRegex.test(value))
		{
			var m = arrayRegex.exec(value);
			value = m.values.length > 0 ? m.values.split(/\s*,\s*/) : [];
		}
		
		result[match.name] = value;
	}
	
	return result;
};

/**
 * Wraps each line of the string into <code/> tag with given style applied to it.
 * 
 * @param {String} str   Input string.
 * @param {String} css   Style name to apply to the string.
 * @return {String}      Returns input string with each line surrounded by <span/> tag.
 */
function wrapLinesWithCode(str, css)
{
	if (str == null || str.length == 0 || str == '\n') 
		return str;

	str = str.replace(/</g, '&lt;');

	// Replace two or more sequential spaces with &nbsp; leaving last space untouched.
	str = str.replace(/ {2,}/g, function(m)
	{
		var spaces = '';
		
		for (var i = 0; i < m.length - 1; i++)
			spaces += sh.config.space;
		
		return spaces + ' ';
	});

	// Split each line and apply <span class="...">...</span> to them so that
	// leading spaces aren't included.
	if (css != null) 
		str = eachLine(str, function(line)
		{
			if (line.length == 0) 
				return '';
			
			var spaces = '';
			
			line = line.replace(/^(&nbsp;| )+/, function(s)
			{
				spaces = s;
				return '';
			});
			
			if (line.length == 0) 
				return spaces;
			
			return spaces + '<code class="' + css + '">' + line + '</code>';
		});

	return str;
};

/**
 * Pads number with zeros until it's length is the same as given length.
 * 
 * @param {Number} number	Number to pad.
 * @param {Number} length	Max string length with.
 * @return {String}			Returns a string padded with proper amount of '0'.
 */
function padNumber(number, length)
{
	var result = number.toString();
	
	while (result.length < length)
		result = '0' + result;
	
	return result;
};

/**
 * Replaces tabs with spaces.
 * 
 * @param {String} code		Source code.
 * @param {Number} tabSize	Size of the tab.
 * @return {String}			Returns code with all tabs replaces by spaces.
 */
function processTabs(code, tabSize)
{
	var tab = '';
	
	for (var i = 0; i < tabSize; i++)
		tab += ' ';

	return code.replace(/\t/g, tab);
};

/**
 * Replaces tabs with smart spaces.
 * 
 * @param {String} code    Code to fix the tabs in.
 * @param {Number} tabSize Number of spaces in a column.
 * @return {String}        Returns code with all tabs replaces with roper amount of spaces.
 */
function processSmartTabs(code, tabSize)
{
	var lines = splitLines(code),
		tab = '\t',
		spaces = ''
		;
	
	// Create a string with 1000 spaces to copy spaces from... 
	// It's assumed that there would be no indentation longer than that.
	for (var i = 0; i < 50; i++) 
		spaces += '                    '; // 20 spaces * 50
			
	// This function inserts specified amount of spaces in the string
	// where a tab is while removing that given tab.
	function insertSpaces(line, pos, count)
	{
		return line.substr(0, pos)
			+ spaces.substr(0, count)
			+ line.substr(pos + 1, line.length) // pos + 1 will get rid of the tab
			;
	};

	// Go through all the lines and do the 'smart tabs' magic.
	code = eachLine(code, function(line)
	{
		if (line.indexOf(tab) == -1) 
			return line;
		
		var pos = 0;
		
		while ((pos = line.indexOf(tab)) != -1) 
		{
			// This is pretty much all there is to the 'smart tabs' logic.
			// Based on the position within the line and size of a tab,
			// calculate the amount of spaces we need to insert.
			var spaces = tabSize - pos % tabSize;
			line = insertSpaces(line, pos, spaces);
		}
		
		return line;
	});
	
	return code;
};

/**
 * Performs various string fixes based on configuration.
 */
function fixInputString(str)
{
	var br = /<br\s*\/?>|&lt;br\s*\/?&gt;/gi;
	
	if (sh.config.bloggerMode == true)
		str = str.replace(br, '\n');

	if (sh.config.stripBrs == true)
		str = str.replace(br, '');
		
	return str;
};

/**
 * Removes all white space at the begining and end of a string.
 * 
 * @param {String} str   String to trim.
 * @return {String}      Returns string without leading and following white space characters.
 */
function trim(str)
{
	return str.replace(/^\s+|\s+$/g, '');
};

/**
 * Unindents a block of text by the lowest common indent amount.
 * @param {String} str   Text to unindent.
 * @return {String}      Returns unindented text block.
 */
function unindent(str)
{
	var lines = splitLines(fixInputString(str)),
		indents = new Array(),
		regex = /^\s*/,
		min = 1000
		;
	
	// go through every line and check for common number of indents
	for (var i = 0; i < lines.length && min > 0; i++) 
	{
		var line = lines[i];
		
		if (trim(line).length == 0) 
			continue;
		
		var matches = regex.exec(line);
		
		// In the event that just one line doesn't have leading white space
		// we can't unindent anything, so bail completely.
		if (matches == null) 
			return str;
			
		min = Math.min(matches[0].length, min);
	}
	
	// trim minimum common number of white space from the begining of every line
	if (min > 0) 
		for (var i = 0; i < lines.length; i++) 
			lines[i] = lines[i].substr(min);
	
	return lines.join('\n');
};

/**
 * Callback method for Array.sort() which sorts matches by
 * index position and then by length.
 * 
 * @param {Match} m1	Left object.
 * @param {Match} m2    Right object.
 * @return {Number}     Returns -1, 0 or -1 as a comparison result.
 */
function matchesSortCallback(m1, m2)
{
	// sort matches by index first
	if(m1.index < m2.index)
		return -1;
	else if(m1.index > m2.index)
		return 1;
	else
	{
		// if index is the same, sort by length
		if(m1.length < m2.length)
			return -1;
		else if(m1.length > m2.length)
			return 1;
	}
	
	return 0;
};

/**
 * Executes given regular expression on provided code and returns all
 * matches that are found.
 * 
 * @param {String} code    Code to execute regular expression on.
 * @param {Object} regex   Regular expression item info from <code>regexList</code> collection.
 * @return {Array}         Returns a list of Match objects.
 */ 
function getMatches(code, regexInfo)
{
	function defaultAdd(match, regexInfo)
	{
		return match[0];
	};
	
	var index = 0,
		match = null,
		matches = [],
		func = regexInfo.func ? regexInfo.func : defaultAdd
		;
	
	while((match = regexInfo.regex.exec(code)) != null)
	{
		var resultMatch = func(match, regexInfo);
		
		if (typeof(resultMatch) == 'string')
			resultMatch = [new sh.Match(resultMatch, match.index, regexInfo.css)];

		matches = matches.concat(resultMatch);
	}
	
	return matches;
};

/**
 * Turns all URLs in the code into <a/> tags.
 * @param {String} code Input code.
 * @return {String} Returns code with </a> tags.
 */
function processUrls(code)
{
	var gt = /(.*)((&gt;|&lt;).*)/;
	
	return code.replace(sh.regexLib.url, function(m)
	{
		var suffix = '',
			match = null
			;
		
		// We include &lt; and &gt; in the URL for the common cases like <http://google.com>
		// The problem is that they get transformed into &lt;http://google.com&gt;
		// Where as &gt; easily looks like part of the URL string.
	
		if (match = gt.exec(m))
		{
			m = match[1];
			suffix = match[2];
		}
		
		return '<a href="' + m + '">' + m + '</a>' + suffix;
	});
};

/**
 * Finds all <SCRIPT TYPE="syntaxhighlighter" /> elementss.
 * @return {Array} Returns array of all found SyntaxHighlighter tags.
 */
function getSyntaxHighlighterScriptTags()
{
	var tags = document.getElementsByTagName('script'),
		result = []
		;
	
	for (var i = 0; i < tags.length; i++)
		if (tags[i].type == 'syntaxhighlighter')
			result.push(tags[i]);
			
	return result;
};

/**
 * Strips <![CDATA[]]> from <SCRIPT /> content because it should be used
 * there in most cases for XHTML compliance.
 * @param {String} original	Input code.
 * @return {String} Returns code without leading <![CDATA[]]> tags.
 */
function stripCData(original)
{
	var left = '<![CDATA[',
		right = ']]>',
		// for some reason IE inserts some leading blanks here
		copy = trim(original),
		changed = false,
		leftLength = left.length,
		rightLength = right.length
		;
	
	if (copy.indexOf(left) == 0)
	{
		copy = copy.substring(leftLength);
		changed = true;
	}
	
	var copyLength = copy.length;
	
	if (copy.indexOf(right) == copyLength - rightLength)
	{
		copy = copy.substring(0, copyLength - rightLength);
		changed = true;
	}
	
	return changed ? copy : original;
};


/**
 * Quick code mouse double click handler.
 */
function quickCodeHandler(e)
{
	var target = e.target,
		highlighterDiv = findParentElement(target, '.syntaxhighlighter'),
		container = findParentElement(target, '.container'),
		textarea = document.createElement('textarea'),
		highlighter
		;

	if (!container || !highlighterDiv || findElement(container, 'textarea'))
		return;

	highlighter = getHighlighterById(highlighterDiv.id);
	
	// add source class name
	addClass(highlighterDiv, 'source');

	// Have to go over each line and grab it's text, can't just do it on the
	// container because Firefox loses all \n where as Webkit doesn't.
	var lines = container.childNodes,
		code = []
		;
	
	for (var i = 0; i < lines.length; i++)
		code.push(lines[i].innerText || lines[i].textContent);
	
	// using \r instead of \r or \r\n makes this work equally well on IE, FF and Webkit
	code = code.join('\r');
	
	// inject <textarea/> tag
	textarea.appendChild(document.createTextNode(code));
	container.appendChild(textarea);
	
	// preselect all text
	textarea.focus();
	textarea.select();
	
	// set up handler for lost focus
	attachEvent(textarea, 'blur', function(e)
	{
		textarea.parentNode.removeChild(textarea);
		removeClass(highlighterDiv, 'source');
	});
};

/**
 * Match object.
 */
sh.Match = function(value, index, css)
{
	this.value = value;
	this.index = index;
	this.length = value.length;
	this.css = css;
	this.brushName = null;
};

sh.Match.prototype.toString = function()
{
	return this.value;
};

/**
 * Simulates HTML code with a scripting language embedded.
 * 
 * @param {String} scriptBrushName Brush name of the scripting language.
 */
sh.HtmlScript = function(scriptBrushName)
{
	var brushClass = findBrush(scriptBrushName),
		scriptBrush,
		xmlBrush = new sh.brushes.Xml(),
		bracketsRegex = null,
		ref = this,
		methodsToExpose = 'getDiv getHtml init'.split(' ')
		;

	if (brushClass == null)
		return;
	
	scriptBrush = new brushClass();
	
	for(var i = 0; i < methodsToExpose.length; i++)
		// make a closure so we don't lose the name after i changes
		(function() {
			var name = methodsToExpose[i];
			
			ref[name] = function()
			{
				return xmlBrush[name].apply(xmlBrush, arguments);
			};
		})();
	
	if (scriptBrush.htmlScript == null)
	{
		alert(sh.config.strings.brushNotHtmlScript + scriptBrushName);
		return;
	}
	
	xmlBrush.regexList.push(
		{ regex: scriptBrush.htmlScript.code, func: process }
	);
	
	function offsetMatches(matches, offset)
	{
		for (var j = 0; j < matches.length; j++) 
			matches[j].index += offset;
	}
	
	function process(match, info)
	{
		var code = match.code,
			matches = [],
			regexList = scriptBrush.regexList,
			offset = match.index + match.left.length,
			htmlScript = scriptBrush.htmlScript,
			result
			;

		// add all matches from the code
		for (var i = 0; i < regexList.length; i++)
		{
			result = getMatches(code, regexList[i]);
			offsetMatches(result, offset);
			matches = matches.concat(result);
		}
		
		// add left script bracket
		if (htmlScript.left != null && match.left != null)
		{
			result = getMatches(match.left, htmlScript.left);
			offsetMatches(result, match.index);
			matches = matches.concat(result);
		}
		
		// add right script bracket
		if (htmlScript.right != null && match.right != null)
		{
			result = getMatches(match.right, htmlScript.right);
			offsetMatches(result, match.index + match[0].lastIndexOf(match.right));
			matches = matches.concat(result);
		}
		
		for (var j = 0; j < matches.length; j++)
			matches[j].brushName = brushClass.brushName;
			
		return matches;
	}
};

/**
 * Main Highlither class.
 * @constructor
 */
sh.Highlighter = function()
{
	// not putting any code in here because of the prototype inheritance
};

sh.Highlighter.prototype = {
	/**
	 * Returns value of the parameter passed to the highlighter.
	 * @param {String} name				Name of the parameter.
	 * @param {Object} defaultValue		Default value.
	 * @return {Object}					Returns found value or default value otherwise.
	 */
	getParam: function(name, defaultValue)
	{
		var result = this.params[name];
		return toBoolean(result == null ? defaultValue : result);
	},
	
	/**
	 * Shortcut to document.createElement().
	 * @param {String} name		Name of the element to create (DIV, A, etc).
	 * @return {HTMLElement}	Returns new HTML element.
	 */
	create: function(name)
	{
		return document.createElement(name);
	},
	
	/**
	 * Applies all regular expression to the code and stores all found
	 * matches in the `this.matches` array.
	 * @param {Array} regexList		List of regular expressions.
	 * @param {String} code			Source code.
	 * @return {Array}				Returns list of matches.
	 */
	findMatches: function(regexList, code)
	{
		var result = [];
		
		if (regexList != null)
			for (var i = 0; i < regexList.length; i++) 
				// BUG: length returns len+1 for array if methods added to prototype chain (oising@gmail.com)
				if (typeof (regexList[i]) == "object")
					result = result.concat(getMatches(code, regexList[i]));
		
		// sort and remove nested the matches
		return this.removeNestedMatches(result.sort(matchesSortCallback));
	},
	
	/**
	 * Checks to see if any of the matches are inside of other matches. 
	 * This process would get rid of highligted strings inside comments, 
	 * keywords inside strings and so on.
	 */
	removeNestedMatches: function(matches)
	{
		// Optimized by Jose Prado (http://joseprado.com)
		for (var i = 0; i < matches.length; i++) 
		{ 
			if (matches[i] === null)
				continue;
			
			var itemI = matches[i],
				itemIEndPos = itemI.index + itemI.length
				;
			
			for (var j = i + 1; j < matches.length && matches[i] !== null; j++) 
			{
				var itemJ = matches[j];
				
				if (itemJ === null) 
					continue;
				else if (itemJ.index > itemIEndPos) 
					break;
				else if (itemJ.index == itemI.index && itemJ.length > itemI.length)
					matches[i] = null;
				else if (itemJ.index >= itemI.index && itemJ.index < itemIEndPos) 
					matches[j] = null;
			}
		}
		
		return matches;
	},
	
	/**
	 * Creates an array containing integer line numbers starting from the 'first-line' param.
	 * @return {Array} Returns array of integers.
	 */
	figureOutLineNumbers: function(code)
	{
		var lines = [],
			firstLine = parseInt(this.getParam('first-line'))
			;
		
		eachLine(code, function(line, index)
		{
			lines.push(index + firstLine);
		});
		
		return lines;
	},
	
	/**
	 * Determines if specified line number is in the highlighted list.
	 */
	isLineHighlighted: function(lineNumber)
	{
		var list = this.getParam('highlight', []);
		
		if (typeof(list) != 'object' && list.push == null) 
			list = [ list ];
		
		return indexOf(list, lineNumber.toString()) != -1;
	},
	
	/**
	 * Generates HTML markup for a single line of code while determining alternating line style.
	 * @param {Integer} lineNumber	Line number.
	 * @param {String} code Line	HTML markup.
	 * @return {String}				Returns HTML markup.
	 */
	getLineHtml: function(lineIndex, lineNumber, code)
	{
		var classes = [
			'line',
			'number' + lineNumber,
			'index' + lineIndex,
			'alt' + (lineNumber % 2 == 0 ? 1 : 2).toString()
		];
		
		if (this.isLineHighlighted(lineNumber))
		 	classes.push('highlighted');
		
		if (lineNumber == 0)
			classes.push('break');
			
		return '<div class="' + classes.join(' ') + '">' + code + '</div>';
	},
	
	/**
	 * Generates HTML markup for line number column.
	 * @param {String} code			Complete code HTML markup.
	 * @param {Array} lineNumbers	Calculated line numbers.
	 * @return {String}				Returns HTML markup.
	 */
	getLineNumbersHtml: function(code, lineNumbers)
	{
		var html = '',
			count = splitLines(code).length,
			firstLine = parseInt(this.getParam('first-line')),
			pad = this.getParam('pad-line-numbers')
			;
		
		if (pad == true)
			pad = (firstLine + count - 1).toString().length;
		else if (isNaN(pad) == true)
			pad = 0;
			
		for (var i = 0; i < count; i++)
		{
			var lineNumber = lineNumbers ? lineNumbers[i] : firstLine + i,
				code = lineNumber == 0 ? sh.config.space : padNumber(lineNumber, pad)
				;
				
			html += this.getLineHtml(i, lineNumber, code);
		}
		
		return html;
	},
	
	/**
	 * Splits block of text into individual DIV lines.
	 * @param {String} code			Code to highlight.
	 * @param {Array} lineNumbers	Calculated line numbers.
	 * @return {String}				Returns highlighted code in HTML form.
	 */
	getCodeLinesHtml: function(html, lineNumbers)
	{
		html = trim(html);
		
		var lines = splitLines(html),
			padLength = this.getParam('pad-line-numbers'),
			firstLine = parseInt(this.getParam('first-line')),
			html = '',
			brushName = this.getParam('brush')
			;

		for (var i = 0; i < lines.length; i++)
		{
			var line = lines[i],
				indent = /^(&nbsp;|\s)+/.exec(line),
				spaces = null,
				lineNumber = lineNumbers ? lineNumbers[i] : firstLine + i;
				;

			if (indent != null)
			{
				spaces = indent[0].toString();
				line = line.substr(spaces.length);
				spaces = spaces.replace(' ', sh.config.space);
			}

			line = trim(line);
			
			if (line.length == 0)
				line = sh.config.space;
			
			html += this.getLineHtml(
				i,
				lineNumber, 
				(spaces != null ? '<code class="' + brushName + ' spaces">' + spaces + '</code>' : '') + line
			);
		}
		
		return html;
	},
	
	/**
	 * Returns HTML for the table title or empty string if title is null.
	 */
	getTitleHtml: function(title)
	{
		return title ? '<caption>' + title + '</caption>' : '';
	},
	
	/**
	 * Finds all matches in the source code.
	 * @param {String} code		Source code to process matches in.
	 * @param {Array} matches	Discovered regex matches.
	 * @return {String} Returns formatted HTML with processed mathes.
	 */
	getMatchesHtml: function(code, matches)
	{
		var pos = 0, 
			result = '',
			brushName = this.getParam('brush', '')
			;
		
		function getBrushNameCss(match)
		{
			var result = match ? (match.brushName || brushName) : brushName;
			return result ? result + ' ' : '';
		};
		
		// Finally, go through the final list of matches and pull the all
		// together adding everything in between that isn't a match.
		for (var i = 0; i < matches.length; i++) 
		{
			var match = matches[i],
				matchBrushName
				;
			
			if (match === null || match.length === 0) 
				continue;
			
			matchBrushName = getBrushNameCss(match);
			
			result += wrapLinesWithCode(code.substr(pos, match.index - pos), matchBrushName + 'plain')
					+ wrapLinesWithCode(match.value, matchBrushName + match.css)
					;

			pos = match.index + match.length + (match.offset || 0);
		}

		// don't forget to add whatever's remaining in the string
		result += wrapLinesWithCode(code.substr(pos), getBrushNameCss() + 'plain');

		return result;
	},
	
	/**
	 * Generates HTML markup for the whole syntax highlighter.
	 * @param {String} code Source code.
	 * @return {String} Returns HTML markup.
	 */
	getHtml: function(code)
	{
		var html = '',
			classes = [ 'syntaxhighlighter' ],
			tabSize,
			matches,
			lineNumbers
			;
		
		// process light mode
		if (this.getParam('light') == true)
			this.params.toolbar = this.params.gutter = false;

		className = 'syntaxhighlighter';

		if (this.getParam('collapse') == true)
			classes.push('collapsed');
		
		if ((gutter = this.getParam('gutter')) == false)
			classes.push('nogutter');

		// add custom user style name
		classes.push(this.getParam('class-name'));

		// add brush alias to the class name for custom CSS
		classes.push(this.getParam('brush'));

		code = trimFirstAndLastLines(code)
			.replace(/\r/g, ' ') // IE lets these buggers through
			;

		tabSize = this.getParam('tab-size');

		// replace tabs with spaces
		code = this.getParam('smart-tabs') == true
			? processSmartTabs(code, tabSize)
			: processTabs(code, tabSize)
			;

		// unindent code by the common indentation
		code = unindent(code);

		if (gutter)
			lineNumbers = this.figureOutLineNumbers(code);
		
		// find matches in the code using brushes regex list
		matches = this.findMatches(this.regexList, code);
		// processes found matches into the html
		html = this.getMatchesHtml(code, matches);
		// finally, split all lines so that they wrap well
		html = this.getCodeLinesHtml(html, lineNumbers);

		// finally, process the links
		if (this.getParam('auto-links'))
			html = processUrls(html);
		
		if (typeof(navigator) != 'undefined' && navigator.userAgent && navigator.userAgent.match(/MSIE/))
			classes.push('ie');
		
		html = 
			'<div id="' + getHighlighterId(this.id) + '" class="' + classes.join(' ') + '">'
				+ (this.getParam('toolbar') ? sh.toolbar.getHtml(this) : '')
				+ '<table border="0" cellpadding="0" cellspacing="0">'
					+ this.getTitleHtml(this.getParam('title'))
					+ '<tbody>'
						+ '<tr>'
							+ (gutter ? '<td class="gutter">' + this.getLineNumbersHtml(code) + '</td>' : '')
							+ '<td class="code">'
								+ '<div class="container">'
									+ html
								+ '</div>'
							+ '</td>'
						+ '</tr>'
					+ '</tbody>'
				+ '</table>'
			+ '</div>'
			;
			
		return html;
	},
	
	/**
	 * Highlights the code and returns complete HTML.
	 * @param {String} code     Code to highlight.
	 * @return {Element}        Returns container DIV element with all markup.
	 */
	getDiv: function(code)
	{
		if (code === null) 
			code = '';
		
		this.code = code;

		var div = this.create('div');

		// create main HTML
		div.innerHTML = this.getHtml(code);
		
		// set up click handlers
		if (this.getParam('toolbar'))
			attachEvent(findElement(div, '.toolbar'), 'click', sh.toolbar.handler);
		
		if (this.getParam('quick-code'))
			attachEvent(findElement(div, '.code'), 'dblclick', quickCodeHandler);
		
		return div;
	},
	
	/**
	 * Initializes the highlighter/brush.
	 *
	 * Constructor isn't used for initialization so that nothing executes during necessary
	 * `new SyntaxHighlighter.Highlighter()` call when setting up brush inheritence.
	 *
	 * @param {Hash} params Highlighter parameters.
	 */
	init: function(params)
	{
		this.id = guid();
		
		// register this instance in the highlighters list
		storeHighlighter(this);
		
		// local params take precedence over defaults
		this.params = merge(sh.defaults, params || {})
		
		// process light mode
		if (this.getParam('light') == true)
			this.params.toolbar = this.params.gutter = false;
	},
	
	/**
	 * Converts space separated list of keywords into a regular expression string.
	 * @param {String} str    Space separated keywords.
	 * @return {String}       Returns regular expression string.
	 */
	getKeywords: function(str)
	{
		str = str
			.replace(/^\s+|\s+$/g, '')
			.replace(/\s+/g, '|')
			;
		
		return '\\b(?:' + str + ')\\b';
	},
	
	/**
	 * Makes a brush compatible with the `html-script` functionality.
	 * @param {Object} regexGroup Object containing `left` and `right` regular expressions.
	 */
	forHtmlScript: function(regexGroup)
	{
		this.htmlScript = {
			left : { regex: regexGroup.left, css: 'script' },
			right : { regex: regexGroup.right, css: 'script' },
			code : new XRegExp(
				"(?<left>" + regexGroup.left.source + ")" +
				"(?<code>.*?)" +
				"(?<right>" + regexGroup.right.source + ")",
				"sgi"
				)
		};
	}
}; // end of Highlighter

return sh;
}(); // end of anonymous function

// CommonJS
typeof(exports) != 'undefined' ? exports['SyntaxHighlighter'] = SyntaxHighlighter : null;
</script><script type="text/javascript">// (inc clojure-brush) ;; an improved SyntaxHighlighter brush for clojure
//
// Copyright (C) 2011 Andrew Brehaut
//
// Distributed under the Eclipse Public License, the same as Clojure.
//
// https://github.com/brehaut/inc-clojure-brush
//
// Written by Andrew Brehaut
// V0.9.1, November 2011

if (typeof net == "undefined") net = {};
if (!(net.brehaut)) net.brehaut = {};

net.brehaut.ClojureTools = (function (SH) {
  "use strict";
  // utiliies
  if (!Object.create) Object.create = function object(o) {
    function F() {};
    F.prototype = o;  
    return new F();
  };
        
  // data
  
  function Token(value, index, tag, length) {
    this.value = value;
    this.index = index;
    this.length = length || value.length;
    this.tag = tag;
    this.secondary_tags = {};
  }
  
  // null_token exists so that LispNodes that have not had a closing tag attached
  // can have a dummy token to simplify annotation
  var null_token = new Token("", -1, "null", -1);
  
  /* LispNodes are aggregate nodes for sexpressions. 
   *
   */
  function LispNode(tag, children, opening) {
    this.tag = tag;            // current metadata for syntax inference
    this.parent = null;        // the parent expression
    this.list = children;      // all the child forms in order
    this.opening = opening;    // the token that opens this form.
    this.closing = null_token; // the token that closes this form.
    this.meta = null;          // metadata nodes will be attached here if they are found
  }

  var null_lispnode = new LispNode("null", [], null_token);

  
  function PrefixNode(tag, token, attached_node) {
    this.tag = tag;
    this.token = token;
    this.attached_node = attached_node;
    this.parent = null;
  }

  
  
  // tokenize

  function tokenize(code) {
    var tokens = [];
    var tn = 0;
    
    var zero = "0".charCodeAt(0);
    var nine = "9".charCodeAt(0); 
    var lower_a = "a".charCodeAt(0);
    var lower_f = "f".charCodeAt(0);    
    var upper_a = "A".charCodeAt(0);
    var upper_f = "F".charCodeAt(0);
    
    var dispatch = false; // have we just seen a # character?
    
    // i tracks the start of the current window
    // extent is the window for slicing
    
    for (var i = 0, 
             extent = i, 
             j = code.length; 
             i < j && extent <= j;) {          
                
      var c = code[i];
      
      // we care about capturing the whole token when dispatch is used, so back up the
      // starting index by 1
      if (dispatch) i--; 
      
      switch (c) {
        // dispatch alters the value of the next thing read
        case "#":
          dispatch = true;
          i++;
          extent++;
          continue;
          
        case " ":    // ignore whitespace
        case "\t":
        case "\n":
        case "\r":
        case ",":   
          extent++
          break; 
          
        // simple terms
        case "^":
        case "`":
        case ")":
        case "[":
        case "]":
        case "}":
        case "@":
          tokens[tn++] = new Token(c, i, c, ++extent - i);
          break;
        
        case "'":
          tokens[tn++] = new Token(code.slice(i, ++extent), i, dispatch ? "#'" : "'", extent - i);
          break
        
        case "(":
          tokens[tn++] = new Token(code.slice(i, ++extent), i, "(", extent - i);
          break;          
          
        case "{":
          tokens[tn++] = new Token(code.slice(i, ++extent), i, dispatch ? "#{" : "{", extent - i);
          break;  
        
        case "\\":
          if (code.slice(i + 1, i + 8) === "newline") {
            tokens[tn++] = new Token("\\newline", i, "value", 8);
            extent = i + 9; 
          }
          else if (code.slice(i + 1, i + 6) === "space") {
            tokens[tn++] = new Token("\\space", i, "value", 6);
            extent = i + 6;
          }
          else if (code.slice(i + 1, i + 4) === "tab") {
            tokens[tn++] = new Token("\\tab", i, "value", 4);
            extent = i + 5;
          } // work around fun bug with &,>,< in character literals
          else if (code.slice(i + 1, i + 6) === "&amp;") {
            tokens[tn++] = new Token("\\&amp;", i, "value", 6);
            extent = i + 6; 
          }
          else if (code.slice(i + 1, i + 5) === "&lt;") {
            tokens[tn++] = new Token("\\&lt;", i, "value", 5);
            extent = i + 5;
          }
          else if (code.slice(i + 1, i + 5) === "&gt;") {
            tokens[tn++] = new Token("\\&gt;", i, "value", 5);
            extent = i + 5;
          }
          
          else {
            extent += 2;
            tokens[tn++] = new Token(code.slice(i, extent), i, "value", 2);
          }
          break;
        
        case "~": // slice
          if (code[i + 1] === "@") {
            extent += 2;
            tokens[tn++] = new Token(code.slice(i, extent), i, "splice", 2);
          }
          else {
            tokens[tn++] = new Token(code.slice(i, ++extent), i, "unquote", 2);
          }
          break;
        
        // complicated terms
        case "\"": // strings and regexps
          for (extent++; extent <= j; extent++) {
            if (code[extent] === "\\") extent++;
            else if (code[extent] === "\"") break;
          }
          tokens[tn++] = new Token(code.slice(i, ++extent), i, dispatch ? "regexp" : "string", extent - i);       
          break;
          
        case ";":
          for (; extent <= j && code[extent] !== "\n" && code[extent] !== "\r"; extent++);
          tokens[tn++] = new Token(code.slice(i, ++extent), i, "comments", extent - i);   
          break;
        
        case "+": // numbers; fall through to symbol for + and - not prefixing a number
        case "-":
        case "0":
        case "1":
        case "2":
        case "3":
        case "4":
        case "5":
        case "6":
        case "7":
        case "8":
        case "9":
        // todo: exponents, hex
        // http://my.safaribooksonline.com/9781449310387/14?reader=pf&readerfullscreen=&readerleftmenu=1
          var c2 = code.charCodeAt(i + 1);
          if (((c === "+" || c === "-") && (c2 >= zero && c2 <= nine)) // prefixes
              || (c !== "+" && c !== "-")) {
            if (c === "+" || c === "-") extent++; 
            for (; extent <= j; extent++) {
              var charCode = code.charCodeAt(extent);
              if (charCode < zero || charCode > nine) break;
            }
            
            c = code[extent];
            c2 = code.charCodeAt(extent + 1);
            if ((c === "r" || c === "R" || c === "/" || c === ".") // interstitial characters
                && (c2 >= zero && c2 <= nine)) {
              for (extent++; extent <= j; extent++) {
                var charCode = code.charCodeAt(extent);
                if (charCode < zero || charCode > nine) break;
              }
            }
            
            c = code[extent];
            c2 = code.charCodeAt(extent + 1);
            if ((c === "x" || c === "X") && 
                ((c2 >= zero && c2 <= nine) 
                 || (c2 >= lower_a && c2 <= lower_f)
                 || (c2 >= upper_a && c2 <= upper_f))) {
              for (extent++; extent <= j; extent++) {
                var charCode = code.charCodeAt(extent);
                if (((charCode >= zero && charCode <= nine) 
                    || (charCode >= lower_a && charCode <= lower_f)
                    || (charCode >= upper_a && charCode <= upper_f))) continue;
                break;
              }
            }
            
            c = code[extent];
            c2 = code.charCodeAt(extent + 1);
            if ((c === "e" || c === "E") 
                && (c2 >= zero && c2 <= nine)) {
              for (extent++; extent <= j; extent++) {
                var charCode = code.charCodeAt(extent);
                if (charCode < zero || charCode > nine) break;
              }
            }
            
            c = code[extent];
            if (c === "N" || c === "M") extent++;

            tokens[tn++] = new Token(code.slice(i, extent), i, "value", extent - i);
            break;
          }

        case "_":
          if (dispatch && c === "_") {
            tokens[tn++] = new Token(code.slice(i, ++extent), i, "skip", extent - i);
            break;
          } // if not a skip, fall through to symbols
        
        // Allow just about any other symbol as a symbol. This is far more permissive than 
        // clojure actually allows, but should catch any weirdo crap that accidentally gets
        // into the code.
        default: 
          for (extent++; extent <= j; extent++) {
            switch (code[extent]) {
              case " ":
              case "\t":
              case "\n":
              case "\r":
              case "\\":
              case ",":
              case "{":
              case "}":
              case "(":
              case ")":
              case "[":
              case "]":
              case "^":
              case "`":
              case "@":   
                break;
              case ";":   
                // theres a weird bug via syntax highligher that gives us escaped entities.
                // need to watch out for these
                if (code.slice(extent-3, extent+1) === "&lt;"
                    ||code.slice(extent-3, extent+1) === "&gt;"
                    ||code.slice(extent-4, extent+1) === "&amp;") {
                  continue;
                }
                break;
              default:
                continue;
            }
            break;
          }
          
          var value = code.slice(i, extent);
          var tag = "symbol";
          if (value[0] == ":") {
            tag = "keyword";
          }
          else if (value === "true" || value === "false" || value === "nil") {
            tag = "value";
          }
          tokens[tn++] = new Token(value, i, tag, extent - i);
      }
      
      dispatch = false;
      i = extent;
    } 

    return tokens;
  }


  function build_tree(tokens) {
    var toplevel = {
      list: [], 
      tag: "toplevel", 
      parent: null, 
      opening: null,
      closing: null,
      depth: -1
    };
    
    // loop variables hoisted out as semi globals to track position in token stream
    var i = -1;
    var j = tokens.length;
    
    function parse_one(t) {
      // ignore special tokens and forms that dont belong in the tree
      for (; t && (t.tag === "comments" || t.tag === "invalid" || t.tag == "skip") && i < j; ) {
        if (t.tag === "skip") {
          t.tag = "preprocessor";
          annotate_comment(parse_one(tokens[++i]));
        }
        t = tokens[++i];
      }
      
      if (!t) return {}; // hackity hack
      
      switch (t.tag) {
        case "{":
          return build_aggregate(new LispNode("map", [], t), "}");
        case "(":
          return build_aggregate(new LispNode("list", [], t), ")");
        case "#{":
          return build_aggregate(new LispNode("set", [], t), "}");
        case "[":
          return build_aggregate(new LispNode("vector", [], t), "]");
        case "'":
          return new PrefixNode("quote", t, parse_one(tokens[++i]));
        case "#'":
          return new PrefixNode("varquote", t, parse_one(tokens[++i]));  
        case "@":
          return new PrefixNode("deref", t, parse_one(tokens[++i]));  
        case "`":
          return new PrefixNode("quasiquote", t, parse_one(tokens[++i]));  
        case "unquote":
          return new PrefixNode("unquote", t, parse_one(tokens[++i]));
        case "splice":
          return new PrefixNode("splice", t, parse_one(tokens[++i]));  
        case "^":
          t.tag = "meta";
          var meta = parse_one(tokens[++i]);
          var next = parse_one(tokens[++i]);
          next.meta = meta;
          return next;
      }
      
      return t;
    }
    
    // build_aggregate collects to ether sub forms for one aggregate for. 
    function build_aggregate(current, expected_closing) {
      for (i++; i < j; i++) {
        var t = tokens[i];

        if (t.tag === "}" || t.tag === ")" || t.tag === "]") {
          if (t.tag !== expected_closing) t.tag = "invalid";
          current.closing = t;
          if (expected_closing) return current;
        }
        var node = parse_one(t);

        node.parent = current;
        current.list[current.list.length] = node;
      }
      
      return current;
    }
    
    build_aggregate(toplevel, null);
    
    return toplevel;
  }

  // annotation rules to apply to a form based on its head

  var show_locals = true;  // HACK. would rather not use a (semi)-global.

  /* annotate_comment is a special case annotation. 
   * in addition to its role in styling specific forms, it is called by parse_one to
   * ignore any forms skipped with #_
   */ 
  function annotate_comment(exp) {
    exp.tag = "comments";

    if (exp.list) {
      exp.opening.tag = "comments";
      exp.closing.tag = "comments";
    
      for (var i = 0; i < exp.list.length; i++) {
        var child = exp.list[i];
        if (child.list) {
          annotate_comment(child);
        }
        if (child.attached_node) {
          annotate_comment(child.attached_node);
        }
        else {
          child.tag = "comments";
        }
      }
    }
  }

  /* custom annotation rules are stored here */
  var annotation_rules = {};
  
  // this function is exposed to allow ad hoc extension of the customisation rules
  function register_annotation_rule(names, rule) {
    for (var i = 0; i < names.length; i++) {
      annotation_rules[names[i]] = rule;
    }
  }


  function annotate_destructuring (exp, scope) {
    if (exp.list) {
      if (exp.tag === "vector") {
        for (var i = 0; i < exp.list.length; i++) {
          annotate_destructuring(exp.list[i], scope);
        }
      } 
      else if (exp.tag === "map") {
        for (var i = 0; i < exp.list.length; i += 2) {
          var key = exp.list[i];
          var val = exp.list[i + 1];
          
          if (key.tag === "keyword" && val.tag === "vector") {
            for (var ii = 0, jj = val.list.length; ii < jj; ii++) {
              if (val.list[ii].tag !== "symbol") continue;
              val.list[ii].tag = "variable";
              scope[val.list[ii].value] = true;
            }
          }
          else {
            annotate_destructuring(key, scope);
            annotate_expressions(val, scope);
          }
        } 
      }
    } 
    else if (exp.tag === "symbol" && (exp.value !== "&" && exp.value !== "&amp;")){
      exp.tag = "variable";
      scope[exp.value] = true;
    }
  }

  function _annotate_binding_vector (exp, scope) {
    if (exp.tag !== "vector") return;
  
    var bindings = exp.list;

    if (bindings.length % 2 === 1) return;
    
    for (var i = 0; i < bindings.length; i += 2) {
      annotate_destructuring(bindings[i], scope);
      annotate_expressions(bindings[i + 1], scope);
    }    
  }

  function annotate_binding (exp, scope) {
    var bindings = exp.list[1];
    if (!show_locals) return; // HACK

    if (bindings) {
      scope = Object.create(scope);
      _annotate_binding_vector(bindings, scope);
    }
    for (var i = 2; i < exp.list.length; i++) {
      annotate_expressions(exp.list[i], scope);
    }
  }
  
  function _annotate_function_body (exp, scope, start_idx) {
    var argvec = exp.list[start_idx];
    if (argvec.tag !== "vector") return;

    scope = Object.create(scope);

    for (var i = 0, j = argvec.list.length; i < j; i++) {
      annotate_destructuring(argvec.list[i], scope);
    }
    
    for (var i = start_idx, j = exp.list.length; i < j; i++) {
      annotate_expressions(exp.list[i], scope);
    }
  }
  
  function annotate_function (exp, scope) {
    for (var i = 1, j = exp.list.length; i < j; i++) {
      var child = exp.list[i];
      
      if (child.tag === "vector") {
        _annotate_function_body (exp, scope, i);
        return;
      }
      else if (child.tag === "list") {
        _annotate_function_body(child, scope, 0)
      }
    }
  }
  
  function annotate_letfn (exp, scope) {
    scope = Object.create(scope);
    var bindings = exp.list[1];
    
    var fn;
    for (var i = 0, j = bindings.list.length; i < j; i++) {
      fn = bindings.list[i];
      if (!fn.list[0]) continue;
      fn.list[0].tag = "variable";
      scope[fn.list[0].value] = true;
    }
    
    for (i = 0, j = bindings.list.length; i < j; i++) {
      var fn = bindings.list[i];
      annotate_function(fn, scope);
    }
    
    for (i = 2, j = exp.list.length; i < j; i++) {
      annotate_expressions(exp.list[i], scope);
    }
  }

  register_annotation_rule(
    ["comment"],
    annotate_comment
  );
  
  register_annotation_rule(
    ["let", "when-let", "if-let", "binding", "doseq", "for", "dotimes", "let*"],
    annotate_binding
  );
  
  register_annotation_rule(
    ["defn", "defn-", "fn", "bound-fn", "defmacro", "fn*", "defmethod"],
    annotate_function
  );
  
  register_annotation_rule(
    ["letfn"],
    annotate_letfn
  );

  // standard annotations

  function _annotate_metadata_recursive(meta, scope) {
    if (!meta) return;

    if (meta.list !== undefined && meta.list !== null) {
      for (var i = 0, j = meta.list.length; i < j; i++) {
        meta.opening.secondary_tags.meta = true
        meta.closing.secondary_tags.meta = true
        _annotate_metadata_recursive(meta.list[i], scope);
      }
    }
    else if (meta.attached_node) {
      meta.token.secondary_tags.meta = true;
      _annotate_metadata_recursive(meta.attached_node, scope);
    }
    else {
      meta.secondary_tags.meta = true;
    }
  }
  
  function annotate_metadata(exp) {
    if (!(exp && exp.meta)) return;
    var meta = exp.meta;
    
     annotate_expressions(meta, {});    
    _annotate_metadata_recursive(meta, {});
  }


  function annotate_quoted(exp, scope) {
    if (!exp) return;

    if (exp.list !== undefined && exp.list !== null) {
      for (var i = 0, j = exp.list.length; i < j; i++) {
        exp.opening.secondary_tags.quoted = true
        exp.closing.secondary_tags.quoted = true
        annotate_quoted(exp.list[i], scope);
      }
    }
    else if (exp.attached_node) {
      if (exp.tag === "unquote" || exp.tag === "splice") return;
      exp.token.secondary_tags.quoted = true;
      annotate_quoted(exp.attached_node, scope);
    }
    else {
      exp.secondary_tags.quoted = true;
    }
  }


  function annotate_expressions(exp, scope) {
    annotate_metadata(exp);
    
    switch (exp.tag) {
      case "toplevel": 
        for (var i = 0; i < exp.list.length; i++) {
          annotate_expressions(exp.list[i], scope);
        }
        break;
      
      case "list": // functions, macros, special forms, comments
        var head = exp.list[0];
      
        if (head) {
          if (head.tag === "list" || head.tag === "vector" 
           || head.tag === "map" || head.tag === "set") {
            annotate_expressions(head, scope);
          }
          else if (head.attached_node) {
            annotate_expressions(head.attached_node, scope);
          }
          else {
            head.tag = (head.value.match(/(^\.)|(\.$)|[A-Z].*\//)
                        ? "method"
                        : "function");
          }

          // apply specific rules
          if (annotation_rules.hasOwnProperty(head.value)) {
            annotation_rules[head.value](exp, scope);
          } 
          else {
            for (var i = 1; i < exp.list.length; i++) {
              annotate_expressions(exp.list[i], scope);
            }
          } 
        }
        else { // empty list
          exp.opening.tag = "value";
          exp.closing.tag = "value";
        }
      
        break;
      
      case "vector": // data
      case "map":
      case "set":
        for (var i = 0; i < exp.list.length; i++) {
          annotate_expressions(exp.list[i], scope);
        }
        break;
      
      case "symbol":
        if (exp.value.match(/[A-Z].*\/[A-Z_]+/)) {
          exp.tag = "constant";
        }
        else if (show_locals && scope[exp.value]) {
          exp.tag = "variable";
        }
        else if (exp.tag === "symbol" && exp.value.match(/([A-Z].*\/)?[A-Z_]+/)) {
          exp.tag = "type";
        }
        break;
      
      case "quote":
      case "quasiquote":
        annotate_quoted(exp.attached_node, scope);
        
      default:
        if (exp.attached_node) annotate_expressions(exp.attached_node, scope);
    }
  }

  // translation of tag to css:
  var css_translation = {
    "constant":     "constants",
    "keyword":      "constants",
    "method":       "color1",
    "type":         "color3", 
    "function":     "functions",
    "string":       "string",
    "regexp":       "string",
    "value":        "value",
    "comments":     "comments",
    "symbol":       "symbol",
    "variable":     "variable",
    "splice":       "preprocessor", 
    "unquote":      "preprocessor",     
    "preprocessor": "preprocessor",
    "meta":         "preprocessor", 
    "'":            "preprocessor", 
    "#'":           "preprocessor",    
    "(":            "plain",
    ")":            "plain",
    "{":            "keyword",
    "}":            "keyword",
    "#{":           "keyword",   
    "[":            "keyword",
    "]":            "keyword",
    "invalid":      "invalid",
    "@":            "plain" 
  };
  
  function translate_tags_to_css(tokens) {
    for (var i = 0, j = tokens.length; i < j; i++) {
      var token = tokens[i];
      token.css = css_translation[token.tag];
      for (var k in token.secondary_tags) if (token.secondary_tags.hasOwnProperty(k))
        token.css += " " + k ;
    };
  }
  
  
  // create the new brush

  SH.brushes.Clojure = function () {};
  SH.brushes.Clojure.prototype = new SyntaxHighlighter.Highlighter();
  
  SH.brushes.Clojure.prototype.findMatches = function find_matches (regexpList, code) {
    // this is a nasty global hack. need to resolve this
    if (this.params && this.params.locals) {
      show_locals = this.params.locals === true || this.params.locals === "true"; 
    }
    else {
      show_locals = true;
    }
    
    var tokens = tokenize(code);
    annotate_expressions(build_tree(tokens), {});
    translate_tags_to_css(tokens);

    return tokens;
  };
  
  SH.brushes.Clojure.aliases = ['clojure', 'Clojure', 'clj'];
  SH.brushes.Clojure.register_annotation_rule = register_annotation_rule;

  return {
    tokenize: tokenize,
    build_tree: build_tree
  };
})(SyntaxHighlighter);
</script><script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script><title>narjure -- Marginalia</title></head><body><table><tr><td class="docs"><div class="header"><h1 class="project-name"><a href="https://github.com/jarradh/narjure">narjure</a></h1><h2 class="project-version">0.1.0-SNAPSHOT</h2><br /><p>A Clojure implementation of the Non-Axiomatic Reasoning System proposed by Pei Wang.</p>
</div><div class="dependencies"><h3>dependencies</h3><table><tr><td class="dep-name">org.clojure/clojure</td><td class="dotted"><hr /></td><td class="dep-version">1.8.0</td></tr><tr><td class="dep-name">org.clojure/core.logic</td><td class="dotted"><hr /></td><td class="dep-version">0.8.10</td></tr><tr><td class="dep-name">instaparse</td><td class="dotted"><hr /></td><td class="dep-version">1.4.1</td></tr><tr><td class="dep-name">com.rpl/specter</td><td class="dotted"><hr /></td><td class="dep-version">0.9.1</td></tr><tr><td class="dep-name">org.clojure/tools.nrepl</td><td class="dotted"><hr /></td><td class="dep-version">0.2.12</td></tr><tr><td class="dep-name">org.clojure/data.priority-map</td><td class="dotted"><hr /></td><td class="dep-version">0.0.7</td></tr><tr><td class="dep-name">org.clojure/core.match</td><td class="dotted"><hr /></td><td class="dep-version">0.3.0-alpha4</td></tr><tr><td class="dep-name">org.clojure/core.unify</td><td class="dotted"><hr /></td><td class="dep-version">0.5.5</td></tr><tr><td class="dep-name">co.paralleluniverse/pulsar</td><td class="dotted"><hr /></td><td class="dep-version">0.7.5</td></tr><tr><td class="dep-name">org.immutant/immutant</td><td class="dotted"><hr /></td><td class="dep-version">2.1.2</td></tr><tr><td class="dep-name">clj-time</td><td class="dotted"><hr /></td><td class="dep-version">0.11.0</td></tr><tr><td class="dep-name">com.taoensso/timbre</td><td class="dotted"><hr /></td><td class="dep-version">4.3.1</td></tr><tr><td class="dep-name">avl.clj</td><td class="dotted"><hr /></td><td class="dep-version">0.0.9</td></tr><tr><td class="dep-name">org.clojure/math.numeric-tower</td><td class="dotted"><hr /></td><td class="dep-version">0.0.4</td></tr><tr><td class="dep-name">quil</td><td class="dotted"><hr /></td><td class="dep-version">2.4.0</td></tr><tr><td class="dep-name">seesaw</td><td class="dotted"><hr /></td><td class="dep-version">1.4.5</td></tr><tr><td class="dep-name">irclj</td><td class="dotted"><hr /></td><td class="dep-version">0.5.0-alpha4</td></tr></table></div></td><td class="codes" style="text-align: center; vertical-align: middle;color: #666;padding-right:20px"><br /><br /><br />(this space intentionally left almost blank)</td></tr><tr><td class="docs"><div class="toc"><a name="toc"><h3>namespaces</h3></a><ul><li><a href="#nal.core">nal.core</a></li><li><a href="#nal.deriver.backward-rules">nal.deriver.backward-rules</a></li><li><a href="#nal.deriver.key-path">nal.deriver.key-path</a></li><li><a href="#nal.deriver.list-expansion">nal.deriver.list-expansion</a></li><li><a href="#nal.deriver.matching">nal.deriver.matching</a></li><li><a href="#nal.deriver.normalization">nal.deriver.normalization</a></li><li><a href="#nal.deriver.preconditions">nal.deriver.preconditions</a></li><li><a href="#nal.deriver.premises-swapping">nal.deriver.premises-swapping</a></li><li><a href="#nal.deriver.projection-eternalization">nal.deriver.projection-eternalization</a></li><li><a href="#nal.deriver.rules">nal.deriver.rules</a></li><li><a href="#nal.deriver.set-functions">nal.deriver.set-functions</a></li><li><a href="#nal.deriver.substitution">nal.deriver.substitution</a></li><li><a href="#nal.deriver.terms-permutation">nal.deriver.terms-permutation</a></li><li><a href="#nal.deriver.truth">nal.deriver.truth</a></li><li><a href="#nal.deriver.utils">nal.deriver.utils</a></li><li><a href="#nal.deriver">nal.deriver</a></li><li><a href="#nal.reader">nal.reader</a></li><li><a href="#nal.rules">nal.rules</a></li><li><a href="#nal.term_utils">nal.term_utils</a></li><li><a href="#nal.test_utils">nal.test_utils</a></li><li><a href="#narjure.actor.utils">narjure.actor.utils</a></li><li><a href="#narjure.bag">narjure.bag</a></li><li><a href="#narjure.budget-functions">narjure.budget-functions</a></li><li><a href="#narjure.control-utils">narjure.control-utils</a></li><li><a href="#narjure.core">narjure.core</a></li><li><a href="#narjure.debug-util">narjure.debug-util</a></li><li><a href="#narjure.defaults">narjure.defaults</a></li><li><a href="#narjure.general-inference.concept-selector">narjure.general-inference.concept-selector</a></li><li><a href="#narjure.general-inference.general-inferencer">narjure.general-inference.general-inferencer</a></li><li><a href="#narjure.general-inference.inference-request-router">narjure.general-inference.inference-request-router</a></li><li><a href="#narjure.global-atoms">narjure.global-atoms</a></li><li><a href="#narjure.memory-management.concept">narjure.memory-management.concept</a></li><li><a href="#narjure.memory-management.concept-manager">narjure.memory-management.concept-manager</a></li><li><a href="#narjure.memory-management.concept-utils">narjure.memory-management.concept-utils</a></li><li><a href="#narjure.memory-management.forgettor">narjure.memory-management.forgettor</a></li><li><a href="#narjure.memory-management.local-inference.belief-processor">narjure.memory-management.local-inference.belief-processor</a></li><li><a href="#narjure.memory-management.local-inference.goal-processor">narjure.memory-management.local-inference.goal-processor</a></li><li><a href="#narjure.memory-management.local-inference.local-inference-utils">narjure.memory-management.local-inference.local-inference-utils</a></li><li><a href="#narjure.memory-management.local-inference.question-processor">narjure.memory-management.local-inference.question-processor</a></li><li><a href="#narjure.memory-management.local-inference.quest-processor">narjure.memory-management.local-inference.quest-processor</a></li><li><a href="#narjure.memory-management.task-dispatcher">narjure.memory-management.task-dispatcher</a></li><li><a href="#narjure.memory-management.termlink-utils">narjure.memory-management.termlink-utils</a></li><li><a href="#narjure.narsese">narjure.narsese</a></li><li><a href="#narjure.perception-action.derived-load-reducer">narjure.perception-action.derived-load-reducer</a></li><li><a href="#narjure.perception-action.operator-executor">narjure.perception-action.operator-executor</a></li><li><a href="#narjure.perception-action.sentence-parser">narjure.perception-action.sentence-parser</a></li><li><a href="#narjure.perception-action.task-creator">narjure.perception-action.task-creator</a></li><li><a href="#narjure.projection-utils">narjure.projection-utils</a></li><li><a href="#narjure.repl">narjure.repl</a></li><li><a href="#narjure.runtime-utils">narjure.runtime-utils</a></li><li><a href="#narjure.sensorimotor">narjure.sensorimotor</a></li><li><a href="#gui.actors">gui.actors</a></li><li><a href="#gui.globals">gui.globals</a></li><li><a href="#gui.gui">gui.gui</a></li><li><a href="#gui.gui-utils">gui.gui-utils</a></li><li><a href="#gui.hnav">gui.hnav</a></li><li><a href="#gui.hud">gui.hud</a></li><li><a href="#gui.lense">gui.lense</a></li><li><a href="#examples.ircbot">examples.ircbot</a></li><li><a href="#examples.pong">examples.pong</a></li><li><a href="#examples.simplenario">examples.simplenario</a></li><li><a href="#examples.simplepong">examples.simplepong</a></li></ul></div></td><td class="codes">&nbsp;</td></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.core" name="nal.core"><h1 class="project-name">nal.core</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.core
  (:require [nal.deriver.truth :as t]
            [nal.deriver :refer [generate-conclusions]]
            [nal.rules :as r]))</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=25" style="text-decoration:none"Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn choice
  [[f1 c1] [f2 c2]]
  (if (&gt;= c1 c2) [f1 c1] [f2 c2]))</pre></td></tr><tr><td class="docs"><p>Apply these rules to task and belief which apply for the task-type.</p>
</td><td class="codes"><pre class="brush: clojure">(defn inference
  [{:keys [task-type] :as task} belief]
  (generate-conclusions (r/rules task-type) task belief))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def revision t/revision)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(comment
  :shift-occurrence-forward                                 ;pre
  :shift-occurrence-backward                                 ;pre
  :linkage-temporal)</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.backward-rules" name="nal.deriver.backward-rules"><h1 class="project-name">nal.deriver.backward-rules</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.backward-rules
  (:require [nal.deriver.key-path :refer [rule-path]]
            [clojure.string :as s]))</pre></td></tr><tr><td class="docs"><p>Return true if rule allows backward inference.</p>

<p>http://pastebin.com/3zLX7rPx</p>
</td><td class="codes"><pre class="brush: clojure">(defn allow-backward?
  [{:keys [conclusions]}]
  (some #{:allow-backward} (:post (first conclusions))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn has-prefix? [prefix cond]
  &quot;check for example for prefix t in :t/deduction as used by the inference rules&quot;
  (when (keyword? cond)
    (s/starts-with? (str cond) prefix)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn not-equal? [cond]
  &quot;check for not-equal sign&quot;
  (when (coll? cond)
    (= :!= (first cond))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn check-not-equal [pre conclusion]
  &quot;put not equal sign together with its arguments so that it can be executed&quot;
  (if (some not-equal? pre)
    (let [pre (remove not-equal? pre)]
      (if (and (coll? conclusion) (= 3 (count conclusion)))
        (let [[_ t1 t2] conclusion]
          (conj pre (list :!= t1 t2)))
        pre))
    pre))</pre></td></tr><tr><td class="docs"><p>If rule allows backward inference it will be expanded to three rules,
  where first one is the rule itself, and rest rules will be generated by
  swapping conclusion with every premise.</p>
</td><td class="codes"><pre class="brush: clojure">(defn expand-backward-rules
  [{:keys [p1 p2 conclusions pre] :as rule}]
  (mapcat (fn [{:keys [conclusion post] :as fc}]
            (let [post (reduce #(remove (partial has-prefix? %2) %1)
                               post [&quot;:t/&quot; &quot;:d/&quot;])]
              (conj (map
                      (fn [r] (update r :pre conj :question?))
                      [(assoc rule :conclusions [(assoc fc :post post)])
                       (assoc rule :p1 conclusion
                                   :conclusions [{:conclusion p1
                                                  :post       post}]
                                   :full-path (rule-path conclusion p2)
                                   :pre (check-not-equal pre p1))
                       (assoc rule :p2 conclusion
                                   :conclusions [{:conclusion p2
                                                  :post       post}]
                                   :full-path (rule-path p1 conclusion)
                                   :pre (check-not-equal pre p2))])
                    rule)))
          conclusions))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.key-path" name="nal.deriver.key-path"><h1 class="project-name">nal.deriver.key-path</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.key-path
  (:require
    [clojure.core.memoize :refer [lru]]))</pre></td></tr><tr><td class="docs"><p>Generates premises "path" by replacing terms with :any</p>
</td><td class="codes"><pre class="brush: clojure">(defn path
  [statement]
  (if (coll? statement)
    (let [[fst &amp; tail] statement]
      (conj (map path tail) fst))
    :any))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn path-with-max-level
  ([statement] (path-with-max-level 0 statement))
  ([level statement]
   (if (coll? statement)
     (let [[fst &amp; tail] statement]
       (cons fst
             (if (&gt; 1 level)
               (let [next-level (if (= 'conj fst) level (inc level))]
                 (map #(path-with-max-level next-level %) tail))
               (repeat (count tail) :any))))
     :any)))</pre></td></tr><tr><td class="docs"><p>Generates detailed pattern for the rule.</p>
</td><td class="codes"><pre class="brush: clojure">(defn rule-path
  [p1 p2]
  [(path p1) :and (path p2)])</pre></td></tr><tr><td class="docs"><p>Cartesian product.</p>
</td><td class="codes"><pre class="brush: clojure">(defn cart
  [colls]
  (if (empty? colls)
    '(())
    (for [x (first colls)
          more (cart (rest colls))]
      (cons x more))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(declare mpath-invariants)</pre></td></tr><tr><td class="docs"><p>Generates all pathes that will match with path from args.</p>
</td><td class="codes"><pre class="brush: clojure">(defn path-invariants
  [path]
  (if (coll? path)
    (let [[op &amp; args] path
          args-inv (map mpath-invariants args)]
      (concat (cart (concat [[op]] args-inv)) [:any]))
    [path]))</pre></td></tr><tr><td class="docs"><p>Generates all pathes for pair of premises.</p>
</td><td class="codes"><pre class="brush: clojure">#_(def mpath-invariants (memoize path-invariants))
(def mpath-invariants (lru path-invariants :lru/threshold 50))
#_(def mpath-invariants path-invariants)
;(all-paths 'Y '(==&gt; (seq-conj X A1 A2 A3) B))
(defn all-paths
  [p1 p2]
  (let [paths1 (mpath-invariants p1)
        paths2 (mpath-invariants p2)]
    (cart [paths1 [:and] paths2])))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">#_(def mall-paths (memoize all-paths))
(def mall-paths (lru all-paths :lru/threshold 50))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.list-expansion" name="nal.deriver.list-expansion"><h1 class="project-name">nal.deriver.list-expansion</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.list-expansion
  (:require [nal.deriver.utils :refer [walk]]
            [clojure.string :as s]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def max-elements-in-list 7)</pre></td></tr><tr><td class="docs"><p>Finds the first :list element in the rule.</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-list
  [prefix statement]
  (cond
    (and (keyword? statement) (s/starts-with? (str statement) prefix))
    statement
    (coll? statement) (some identity (map #(get-list prefix %) statement))
    :default nil))</pre></td></tr><tr><td class="docs"><p>Generates n symbols with prefix.</p>
</td><td class="codes"><pre class="brush: clojure">(defn gen-symbols
  [prefix n]
  (map #(symbol (str prefix (inc %))) (range n)))</pre></td></tr><tr><td class="docs"><p>Replaces :list/ with symbols.</p>
</td><td class="codes"><pre class="brush: clojure">(defn replace-list-elemets
  [statement l list-name n]
  (walk statement
    (and (coll? el) (some #{l} el))
    (mapcat (fn [e] (if (= l e)
                   (concat '() (gen-symbols list-name n))
                   (list e))) el)))</pre></td></tr><tr><td class="docs"><p>Fetches name of the list.</p>
</td><td class="codes"><pre class="brush: clojure">(defn list-name
  [l]
  (-&gt;&gt; l str (drop 6) s/join))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn expand-:from-element
  &quot;Expands :from/ element in rule, so as a result will be created n rules, in
  each of them :form/A will be replaced with A1 or A2 or A3, etc.&quot;
  [statement from-name list-name n]
  (map (fn [idx]
         (walk statement
           (= from-name el) (symbol (str list-name idx))))
       (range 1 (inc n))))</pre></td></tr><tr><td class="docs"><p>Expands rules with :list/ elements, as a result will be created 5 rules,
  where :list/ will be replaced with A1, A1 A2, ..., A1..A5.</p>
</td><td class="codes"><pre class="brush: clojure">(defn generate-all-lists
  [r]
  (let [list (get-list &quot;:list&quot; r)
        l-name (list-name list)]
    (mapcat #(let [st (replace-list-elemets r list l-name %)]
              (if-let [from-name (get-list &quot;:from&quot; st)]
                (expand-:from-element st from-name l-name %)
                [st]))
            (range 1 (inc max-elements-in-list)))))</pre></td></tr><tr><td class="docs"><p>Checks if rule contains any :list element.</p>
</td><td class="codes"><pre class="brush: clojure">(defn contains-list?
  [r]
  (get-list &quot;:list&quot; r))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.matching" name="nal.deriver.matching"><h1 class="project-name">nal.deriver.matching</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.matching
  (:require
    [nal.deriver.utils :refer [walk operator? not-operator?]]
    [clojure.core.unify :as u]
    [clojure.set :refer [map-invert intersection]]
    [clojure.string :as s]
    [narjure.global-atoms :refer [nars-time]]               ;because of projection!
    [nal.deriver
     [set-functions :refer [f-map not-empty-diff? not-empty-inter?]]
     [substitution :refer [munification-map substitute]]
     [preconditions :refer [sets compound-precondition conclusion-transformation
                            implications-and-equivalences get-terms abs
                            preconditions-transformations]]
     [normalization :refer [commutative-ops sort-commutative reducible-ops]
      :as n]
     [truth :as t]
     [projection-eternalization :refer [project-eternalize-to]]]))</pre></td></tr><tr><td class="docs"><p>operators/functions that shouldn't be quoted</p>
</td><td class="codes"><pre class="brush: clojure">(def reserved-operators
  #{`= `not= `seq? `first `and `let `pos? `&gt; `&gt;= `&lt; `&lt;= `coll? `set `quote
    `count 'aops `- `not-empty-diff? `not-empty-inter? `walk `munification-map
    `substitute `sets `some `deref `do `vreset! `volatile! `fn `mapv `if
    `sort-commutative `n/reduce-ext-inter `complement
    `n/reduce-int-dif `n/reduce-and `n/reduce-ext-dif `n/reduce-image
    `n/reduce-int-inter `n/reduce-neg `n/reduce-or `nil? `not `or `abs
    `implications-and-equivalences `get-terms `empty? `intersection
    `n/reduce-seq-conj})</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn operators-&gt;placeholders
  [statement]
  (walk statement
        (and (symbol? :el)
             (operator? :el)) '_
        (= :interval :el) '_
        (coll? :el) (vec :el)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn quote-operators
  [statement]
  (walk statement
        (and
          (not (reserved-operators :el))
          (symbol? :el)
          (or (operator? :el) (#{'Y 'X} :el))) `'~:el
        (and (coll? :el)
             ((complement map?) :el)
             (let [f (first :el)]
               (and (not (reserved-operators f))
                    (not (fn? f)))))
        (vec :el)))</pre></td></tr><tr><td class="docs"><p>Formation of conclusion in terms of task and truth/desire functions</p>
</td><td class="codes"><pre class="brush: clojure">(defn form-conclusion
  [{:keys [t1 t2 task-type task belief]}
   {c  :statement tf :t-function pj :p/belief df :d-function
    sc :shift-conditions swap-truth :swap-truth time-measured :time-measured}]
  (let [conclusion-type (if pj :belief task-type)
        conclusion {:statement  c
                    :task-type  conclusion-type
                    :occurrence :t-occurrence}
        get-func (fn [f] (let [secure (fn [func t1 t2 task belief swapped time-measure]
                                        (let [belief-truth (fn [t task belief] ;2. this is why args are necessary here
                                                             (if (or (= nil belief)
                                                                     (not (:truth belief)))
                                                               t
                                                               (if time-measure ;as task and belief are not aviable on rule generation
                                                                 #_(:truth (project-eternalize-to (:occurrence task) ;just to play the role of less confidence for further apart
                                                                                                belief @nars-time)) ;not necessary as time is kept track of!!
                                                                 t
                                                                 (:truth (project-eternalize-to (:occurrence task)
                                                                                                belief @nars-time)))))]
                                          (if swapped
                                            (try
                                              (func (belief-truth t2 task belief) t1)
                                              (catch Exception e [0 0]))
                                            (try
                                              (func t1 (belief-truth t2 task belief))
                                              (catch Exception e [0 0])))))]
                           (list secure f t1 t2 task belief swap-truth time-measured))) ;1. at this place the entries are not generated yet!
        conclusion (case conclusion-type
                     :belief (assoc conclusion :truth (get-func tf))
                     :goal (assoc conclusion :truth (get-func df))
                     conclusion)]
    (if sc
      (conclusion-transformation sc conclusion)
      conclusion)))</pre></td></tr><tr><td class="docs"><p>Generates code for precondition node.</p>
</td><td class="codes"><pre class="brush: clojure">(defn traverse-node
  [vars result {:keys [conclusions children condition]}]
  (let [conclusions (remove
                      nil?
                      [(when-not (zero? (count conclusions))
                         `(vswap! ~result concat
                                  ~@(set (map #(mapv (partial form-conclusion vars) %)
                                              (quote-operators conclusions)))))])
        children (mapcat (fn [n] (traverse-node vars result n)) children)]
    (if (true? condition)
      (concat conclusions children)
      [`(when ~(quote-operators condition)
          ~@(concat conclusions children))])))</pre></td></tr><tr><td class="docs"><p>Walk through preconditions tree and generates code for matcher.</p>
</td><td class="codes"><pre class="brush: clojure">(defn traversal
  [vars tree]
  (let [results (gensym)]
    `(let [~results (volatile! [])]
       ~@(traverse-node vars results tree)
       @~results)))</pre></td></tr><tr><td class="docs"><p>Reblaces occurrences keywords from matcher's code by generated symbols.</p>
</td><td class="codes"><pre class="brush: clojure">(defn replace-occurrences
  [code]
  (let [t-occurrence (gensym) b-occurrence (gensym)]
    (walk code
          (= :el :t-occurrence) t-occurrence
          (= :el :b-occurrence) b-occurrence)))</pre></td></tr><tr><td class="docs"><p>Generates code of function that will match premises. Generated function
  should be called with task and belief as arguments.</p>
</td><td class="codes"><pre class="brush: clojure">(defn match-rules
  [rules pattern task-type]
  (let [t1 (gensym) t2 (gensym)
        task (gensym) belief (gensym)
        truth-kw :truth]
    (replace-occurrences
      `(fn [{p1# :statement ~t1 ~truth-kw :t-occurrence :occurrence :as ~task}
            {p2# :statement ~t2 :truth :b-occurrence :occurrence :as ~belief}]
         (let [~(operators-&gt;placeholders (first pattern)) p1#
               ~(operators-&gt;placeholders (second pattern)) p2#]
           ~(traversal {:t1        t1
                        :t2        t2
                        :task      task
                        :belief    belief
                        :task-type task-type}
                       rules))))))</pre></td></tr><tr><td class="docs"><p>Replaces all terms in statemnt to placeholders that will be used in pattern
  matching or unification. Return vector, where the first element is map from
  placeolder to term and the second is statement with replaced terms.
  Form instance:</p>

<p>  (find-and-replace-symbols '[--> [- A B] C] "x")
  ;[{x0 A, x1 B, x2 C} [(quote -->) [(quote -) x0 x1] x2]]</p>
</td><td class="codes"><pre class="brush: clojure">(defn find-and-replace-symbols
  [statement prefix]
  (let [cnt (volatile! 0)
        sym-map (volatile! {})
        get-sym #(symbol (str prefix %))
        result (walk statement
                     (and (symbol? el) (not-operator? el))
                     (let [s (get-sym @cnt)]
                       (vswap! cnt inc)
                       (vswap! sym-map assoc s el)
                       s))]
    [@sym-map result]))</pre></td></tr><tr><td class="docs"><p>Replaces </p>
</td><td class="codes"><pre class="brush: clojure">(defn symbols-&gt;placeholders
  [premise]
  (second (find-and-replace-symbols premise &quot;x&quot;)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn symbol-ordering-keyfn
  [sym]
  (if (symbol? sym)
    (try (Integer/parseInt (s/join (drop 1 (str sym))))
         (catch Exception _ -100))
    -1))</pre></td></tr><tr><td class="docs"><p>Sorts placeholder for preconditions. If we have two precondition like
  (!= x0 x2) and (!= x2 x0) they are equal but we can not check this easely.
  So this function sort [x2 x0] to [x0 x2], so we can reason that
  (!= x0 x2) and (!= x2 x0) are equal.</p>
</td><td class="codes"><pre class="brush: clojure">(defn sort-placeholders
  [tail]
  (sort-by symbol-ordering-keyfn tail))</pre></td></tr><tr><td class="docs"><p>Generates code for preconditions.</p>
</td><td class="codes"><pre class="brush: clojure">(defn apply-preconditions
  [preconditions]
  (reduce (fn [ac condition]
            (if (seq? condition)
              (concat ac (compound-precondition condition))
              ac))
          [] preconditions))</pre></td></tr><tr><td class="docs"><p>Replaces elements from statement if finds them in sym-map.</p>
</td><td class="codes"><pre class="brush: clojure">(defn replace-symbols
  [conclusion sym-map]
  (let [sym-map (map-invert sym-map)]
    (walk conclusion
          (sym-map el) (sym-map el))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn find-kv-by-prefix [prefix coll]
  (first (filter #(and (keyword? %) (s/starts-with? (str %) prefix)) coll)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn get-truth-fn [post] (find-kv-by-prefix &quot;:t/&quot; post))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn get-desire-fn [post] (find-kv-by-prefix &quot;:d/&quot; post))</pre></td></tr><tr><td class="docs"><p>Filter map of symbols and keep only aliases of symbol that have lower
  order-key (to avoid preconditions with swapped symbols, like (= x1 x2)
  (= x2 x1).</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-aliases
  [symbols-map alias]
  (let [sym (symbols-map alias)]
    (-&gt;&gt; (dissoc symbols-map alias)
         (filter (fn [[a v]]
                   (and (&lt; (symbol-ordering-keyfn alias)
                           (symbol-ordering-keyfn a))
                        (= v sym))))
         keys)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn aliases-&gt;conditins
  [symbols-map alias]
  (mapcat #(list `= alias %) (get-aliases symbols-map alias)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn check-conditions [syms]
  (-&gt;&gt; (keys syms)
       (keep (partial aliases-&gt;conditins syms))
       (filter not-empty)))</pre></td></tr><tr><td class="docs"><p>whether the statement is a commutative &lt;-> &amp;&amp;, || etc. statement</p>
</td><td class="codes"><pre class="brush: clojure">(defn commutative?
  [st]
  (and (coll? st) (some commutative-ops st)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn check-commutative [conclusion]
  &quot;generate commutativity check&quot;
  (if (commutative? conclusion)
    `(sort-commutative ~(sort-commutative conclusion))
    conclusion))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn check-reduction [conclusion]
  &quot;generating code for the reduction of the conclusion&quot;
  (walk conclusion
        (and (coll? :el) (reducible-ops (first :el)) (&lt;= 2 (count :el)))
        `(~(reducible-ops (first :el)) ~:el)))</pre></td></tr><tr><td class="docs"><p>find the occurrence time shift preconditions :shift-occurrence-backward and :shift-occurrence-forward</p>
</td><td class="codes"><pre class="brush: clojure">(defn find-shift-precondition
  [preconditions]
  (first
    (filter
      #(and false                                           ;disabled due to new handling!!
            (coll? %)                                       ;TODO remove if successful
            (#{:shift-occurrence-backward
               :shift-occurrence-forward}
              (first %))) preconditions)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn arg-count [f]
  {:pre [(instance? clojure.lang.AFunction f)]}
  (-&gt; f class .getDeclaredMethods first .getParameterTypes alength))</pre></td></tr><tr><td class="docs"><p>Creates map with preconditions and conclusions regarding to the main pattern
     of rules branch.
     Example:</p>

<pre><code> the main pattern of riles branch is
 [[--&gt; :any [- :any :any]] :and [--&gt; :any :any]]

 before it will be applied to pattern matching it will be transformed to
 [[--&gt; x1 [- x2 x3]] [--&gt; x4 x5]]

 When whe want to use the pattern above to derive conclusions from some
 another rule, we have to map placeholders from pattern to terms in this rule.

 For rule with premises [[--&gt; A B] [--&gt; B C]] and conclusion [--&gt; A C]
 map will be
 {x1 A, ['- x2 x3] B, x4 B, x5 C}

 From this map, conditions will be the list with one condition:
 [(= ['- x2 x3] x4)]

 and conclusion will be
 [--&gt; x1 x4].
</code></pre>
</td><td class="codes"><pre class="brush: clojure">  (defn premises-pattern
    [pattern premise {:keys [post conclusion]} preconditions]
    (let [[sym-map pat] (find-and-replace-symbols premise &quot;?a&quot;)
          unification-map (u/unify pattern pat)
          sym-map (into {} (map (fn [[k v]] [(k unification-map) v]) sym-map))
          inverted-sym-map (map-invert sym-map)
          pre (walk (apply-preconditions preconditions)
                    (inverted-sym-map el) (inverted-sym-map el)
                    (seq? el)
                    (let [[f &amp; tail] el]
                      (if-not (#{`munification-map `not-empty-diff?} f)
                        (concat (list f) (sort-placeholders tail))
                        el)))]
      {:conclusion {:statement        (-&gt; conclusion
                                          (preconditions-transformations preconditions)
                                          (replace-symbols sym-map)
                                          check-commutative
                                          check-reduction)
                    :shift-conditions (replace-symbols
                                        (find-shift-precondition preconditions)
                                        sym-map)
                    :t-function       (t/tvtypes (get-truth-fn post))
                    :d-function       (t/dvtypes (get-desire-fn post))
                    :swap-truth       (some #{:truth-swapped} post)
                    :time-measured    (some #{:measure-time} post)
                    :p/belief         (some #{:p/belief} post)}
       :conditions (remove nil?
                           (walk (concat (check-conditions sym-map) pre)
                                 (and (coll? el) (= \a (first (str (first el)))))
                                 (concat '() el)
                                 (and (coll? el) (not ((conj reserved-operators 'quote)
                                                        (first el))))
                                 (vec el)))}))</pre></td></tr><tr><td class="docs"><p>Creates map from conditions to conclusions.</p>
</td><td class="codes"><pre class="brush: clojure">  (defn conditions-&gt;conclusions-map
    [main rules]
    (-&gt;&gt; rules
         (map (fn [[premises conclusions preconditions]]
                (premises-pattern main premises conclusions preconditions)))
         (group-by :conditions)
         (map (fn [[k v]] [k (map :conclusion v)]))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">  (defrecord TreeNode [condition conclusions children])</pre></td></tr><tr><td class="docs"><p>Groups conditions->conclusions map by first condition and remove it.</p>
</td><td class="codes"><pre class="brush: clojure">  (defn group-conditions
    [conds]
    (into {} (map (fn [[k v]]
                    [k (map (fn [[k v]]
                              [(drop 1 k) (set v)]) v)])
                  (group-by #(-&gt; % first first) conds))))</pre></td></tr><tr><td class="docs"><p>Generates tree of conditions from conditions->conclusions map.</p>
</td><td class="codes"><pre class="brush: clojure">  (defn generate-tree
    ([conds] (generate-tree true conds))
    ([cond conds]
     (let [grouped-conditions (group-conditions conds)
           reached-keys (map second (grouped-conditions nil))
           other (dissoc grouped-conditions nil)]
       (-&gt;TreeNode cond reached-keys
                   (map (fn [[cond conds]]
                          (generate-tree cond conds))
                        other)))))</pre></td></tr><tr><td class="docs"><p>Generates the map of priorities for conditions according to their frequency.</p>
</td><td class="codes"><pre class="brush: clojure">  (defn conds-priorities-map
    [conds]
    (-&gt;&gt; (mapcat (fn [[cnds k]]
                   (if (not-empty cnds)
                     (map (fn [c] [c k]) cnds)
                     [(list '() k)])) conds)
         (group-by first)
         (map (fn [[k v]] [k (+ (- (count v)) (rand 0.4))]))
         (into {})))</pre></td></tr><tr><td class="docs"><p>Sorts conditions in conditions->conclusions map according to the map of
     priorities of conditions. If condition occurs frequently it will have higher
     priority.</p>
</td><td class="codes"><pre class="brush: clojure">  (defn sort-conds
    [conds cpm]
    (map (fn [[cnds k]] [(sort-by cpm cnds) k]) conds))</pre></td></tr><tr><td class="docs"><p>Prepeares data for generation of conditions tree and then generates tree.</p>
</td><td class="codes"><pre class="brush: clojure">  (defn gen-rules
    [main-pattern rules]
    (let [rules (mapcat (fn [{:keys [p1 p2 conclusions pre]}]
                          (map #(vector [p1 p2] % pre) conclusions))
                        rules)
          cond-conclusions-m (conditions-&gt;conclusions-map main-pattern rules)
          cpm (conds-priorities-map cond-conclusions-m)
          sorted-conds (sort-conds cond-conclusions-m cpm)]
      (generate-tree sorted-conds)))</pre></td></tr><tr><td class="docs"><p>Generates code for rule matcher.</p>
</td><td class="codes"><pre class="brush: clojure">  (defn generate-matching
    [rules task-type]
    (-&gt;&gt; rules
         (map (fn [[k {:keys [pattern rules] :as v}]]
                (let [main-pattern (symbols-&gt;placeholders pattern)
                      match-fn-code (-&gt; main-pattern
                                        (gen-rules rules)
                                        (match-rules main-pattern task-type))]
                  [k (eval match-fn-code)])))
         (into {})))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.normalization" name="nal.deriver.normalization"><h1 class="project-name">nal.deriver.normalization</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.normalization
  (:require [clojure.string :as s]
            [clojure.set :as set]
            [clojure.core.match :as m]))</pre></td></tr><tr><td class="docs"><p>operators that should be movet from infix to prefix position</p>
</td><td class="codes"><pre class="brush: clojure">(def operators
  #{'&amp;| '--&gt; '&lt;-&gt; '==&gt; 'retro-impl 'pred-impl 'seq-conj 'inst 'prop 'inst-prop
    'int-image 'ext-image '=/&gt; '=|&gt; '| '&lt;=&gt; '&lt;/&gt; '&lt;|&gt; '- 'int-dif '|| '&amp;&amp;
    'ext-inter 'conj})</pre></td></tr><tr><td class="docs"><p>commutative:    &lt;-> &lt;=> &lt;|> &amp; | &amp;&amp; ||
not commutative: --> ==> =/> => </> &amp;/ - ~</p>
</td><td class="codes"></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def commutative-ops #{'&lt;-&gt; '&lt;=&gt; '&lt;|&gt; '| '|| 'conj 'ext-inter '&amp;|})</pre></td></tr><tr><td class="docs"><p>Makes transformaitions like [A --> B] to [--> A B].</p>
</td><td class="codes"><pre class="brush: clojure">(defn infix-&gt;prefix
  [premise]
  (if (coll? premise)
    (let [[f s &amp; tail] premise]
      (map infix-&gt;prefix
           (if (operators s)
             (concat [s f] tail)
             premise)))
    premise))</pre></td></tr><tr><td class="docs"><p>Checks if symbol starts with --, true for --A, --X</p>
</td><td class="codes"><pre class="brush: clojure">(defn- neg-symbol?
  [el]
  (and (not= el '--&gt;) (symbol? el) (s/starts-with? (str el) &quot;--&quot;)))</pre></td></tr><tr><td class="docs"><p>Removes -- from symbols with negation:
  (trim-negation '--A) => A</p>
</td><td class="codes"><pre class="brush: clojure">(defn- trim-negation
  [el]
  (symbol (s/join (drop 2 (str el)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn neg [el] (list '-- el))</pre></td></tr><tr><td class="docs"><p>Replaces negations's "new notation".</p>
</td><td class="codes"><pre class="brush: clojure">(defn replace-negation
  [statement]
  (cond
    (neg-symbol? statement) (neg (trim-negation statement))
    (or (vector? statement) (and (seq? statement) (not= '-- (first statement))))
    (:st
      (reduce
        (fn [{:keys [prev st] :as ac} el]
          (if (= '-- el)
            (assoc ac :prev true)
            (-&gt;&gt; [(cond prev (neg el)
                        (coll? el) (replace-negation el)
                        (neg-symbol? el) (neg (trim-negation el))
                        :else el)]
                 (concat st)
                 (assoc ac :prev false :st))))
        {:prev false :st '()}
        statement))
    :else statement))</pre></td></tr><tr><td class="docs"><p>provide an order for the commutative ops, so that <a &lt;-> b> and <b &lt;-> a> will both be <b &lt;-> a>,
  this is needed because they need to end up in the same concept!</p>

<p>todo make recursive:</p>
</td><td class="codes"><pre class="brush: clojure">(defn sort-commutative
  [conclusions]
  (if (coll? conclusions)
    (if (= (first conclusions) '--)
      ['-- (sort-commutative (second conclusions))]
      (let [f (first conclusions)]
        (if (commutative-ops f)
          (vec (conj (sort-by hash (drop 1 conclusions)) f))
          conclusions)))
    conclusions))</pre></td></tr><tr><td class="docs"><p>the union set operation for extensional and intensional sets</p>

<p>https://gist.github.com/TonyLo1/a3f8e05458c5e90c2e72</p>
</td><td class="codes"><pre class="brush: clojure">(defn union
  ([c1 c2] (sort-by hash (set (concat c1 c2))))
  ([op c1 c2] (vec (conj (union c1 c2) op))))</pre></td></tr><tr><td class="docs"><p>the difference set operation for extensional and intensional sets</p>
</td><td class="codes"><pre class="brush: clojure">(defn diff
  ([c1 c2] (into '() (set/difference (set c1) (set c2))))
  ([op c1 c2] (vec (conj (diff c1 c2) op))))</pre></td></tr><tr><td class="docs"><p>Reductions for extensional intersection.</p>
</td><td class="codes"><pre class="brush: clojure">(defn reduce-ext-inter
  [st]
  (m/match
    st
    [_ t] t
    [_ ['ext-inter &amp; l1] ['ext-inter &amp; l2]] (union 'ext-inter l1 l2)
    [_ ['ext-inter &amp; l1] l2] (union 'ext-inter l1 [l2])
    [_ l1 ['ext-inter &amp; l2]] (union 'ext-inter [l1] l2)
    [_ ['int-set &amp; l1] ['int-set &amp; l2]] (union 'int-set l1 l2)
    ;[_ ['ext-set &amp; l1] ['ext-set &amp; l2]] (union 'ext-set l1 l2)
    :else st))</pre></td></tr><tr><td class="docs"><p>Reductions for intensional intersection</p>
</td><td class="codes"><pre class="brush: clojure">(defn reduce-int-inter
  [st]
  (m/match st
           ['| t] t
           ['| ['| &amp; l1] ['| &amp; l2]] (union '| l1 l2)
           ['| ['| &amp; l1] l2] (union '| l1 [l2])
           ['| l1 ['| &amp; l2]] (union '| [l1] l2)
           ['| ['int-set &amp; l1] ['int-set &amp; l2]] (union 'int-set l1 l2)
           ['| ['ext-set &amp; l1] ['ext-set &amp; l2]] (union 'ext-set l1 l2)
           :else st))</pre></td></tr><tr><td class="docs"><p>Reductions for intensional difference</p>
</td><td class="codes"><pre class="brush: clojure">(defn reduce-int-dif
  [st]
  (m/match st
           [_ ['int-set &amp; l1] ['int-set &amp; l2]] (diff 'int-set l1 l2)
           :else st))</pre></td></tr><tr><td class="docs"><p>Reductions for extensional difference</p>
</td><td class="codes"><pre class="brush: clojure">(defn reduce-ext-dif
  [st]
  (m/match st
           [_ ['ext-set &amp; l1] ['ext-set &amp; l2]] (diff 'ext-set l1 l2)
           :else st))</pre></td></tr><tr><td class="docs"><p>Reductions for images</p>
</td><td class="codes"><pre class="brush: clojure">(defn reduce-image
  [st]
  st
  #_(m/match st
           [_ ['* t1 t2] t3] (if (and (= t2 t3) (not= t1 t2)) t1 st)
           :else st))</pre></td></tr><tr><td class="docs"><p>Reductions for negation</p>
</td><td class="codes"><pre class="brush: clojure">(defn reduce-neg
  [st]
  (m/match st
           ['-- ['-- t]] t
           :else st))</pre></td></tr><tr><td class="docs"><p>Reductions for or</p>
</td><td class="codes"><pre class="brush: clojure">(defn reduce-or
  [st]
  (m/match st
           ['|| t] t
           ['|| ['|| &amp; l1] ['|| &amp; l2]] (union '|| l1 l2)
           ['|| ['|| &amp; l1] l2] (union '|| l1 [l2])
           ['|| l1 ['|| &amp; l2]] (union '|| [l1] l2)
           ['|| t1 t2] (if (= t1 t2) t1 st)
           :else st))</pre></td></tr><tr><td class="docs"><p>Reductions for and</p>
</td><td class="codes"><pre class="brush: clojure">(defn reduce-and
  [st]
  (m/match st
           ['conj t] t
           ['conj ['conj &amp; l1] ['conj &amp; l2]] (union 'conj l1 l2)
           ['conj ['conj &amp; l1] l2] (union 'conj l1 [l2])
           ['conj l1 ['conj &amp; l2]] (union 'conj [l1] l2)
           ['conj t1 t2] (if (= t1 t2) t1 st)
           :else st))</pre></td></tr><tr><td class="docs"><p>Not in use currently, may change</p>
</td><td class="codes"><pre class="brush: clojure">(defn reduce-seq-conj
  [st]
  st)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def reducible-ops
  {'ext-inter `reduce-ext-inter
   '|         `reduce-int-inter
   '-         `reduce-ext-dif
   'int-dif   `reduce-int-dif
   'int-image `reduce-image
   'ext-image `reduce-image
   '--        `reduce-neg
   'conj      `reduce-and
   '||        `reduce-or})</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn reduce-ops
  [st]
  (let [f (first st)]
    (case f
      ext-inter (reduce-ext-inter st)
      | (reduce-int-inter st)
      - (reduce-ext-dif st)
      int-dif (reduce-int-dif st)
      int-image (reduce-image st)
      ext-image (reduce-image st)
      -- (reduce-neg st)
      conj (reduce-and st)
      || (reduce-or st)
      st)))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.preconditions" name="nal.deriver.preconditions"><h1 class="project-name">nal.deriver.preconditions</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.preconditions
  (:require [nal.deriver.set-functions
             :refer [f-map not-empty-diff? not-empty-inter?]]
            [nal.deriver.utils :refer [walk postwalk-depth1]]
            [nal.deriver.substitution :refer [substitute munification-map]]
            [nal.deriver.terms-permutation :refer [implications equivalences]]
            [clojure.set :refer [union intersection]]
            [narjure.defaults :refer [temporal-window-duration]]
            [clojure.core.match :as m]
            [nal.deriver.normalization :refer [reduce-seq-conj]]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn abs [^long n] (Math/abs n))</pre></td></tr><tr><td class="docs"><p>Expands compound precondition to clojure sequence
  that will be evaluted later</p>

<p>TODO preconditions
:shift-occurrence-forward :shift-occurrence-backward</p>
</td><td class="codes"><pre class="brush: clojure">(defmulti compound-precondition
  first)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :default [_] [])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :!=
  [[_ &amp; args]]
  [`(not= ~@args)])</pre></td></tr><tr><td class="docs"><p>Whether it is a extensional or intensional set</p>
</td><td class="codes"><pre class="brush: clojure">(defn check-set
  [set-type arg]
  `(and (coll? ~arg) (= ~set-type (first ~arg))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :set-ext? [[_ arg]]
  [(check-set 'ext-set arg)])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :set-int? [[_ arg]]
  [(check-set 'int-set arg)])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def sets '#{ext-set int-set})</pre></td></tr><tr><td class="docs"><p>Set condition handling</p>
</td><td class="codes"><pre class="brush: clojure">(defn set-conditions
  [set1 set2]
  [`(coll? ~set1)
   `(coll? ~set2)
   `(let [k# 1 afop# (first ~set1)]
      (and (sets afop#) (= afop# (first ~set2))))])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :difference [[_ arg1 arg2]]
  &quot;Set difference precondition predicate, it is only true if the last arg is the difference of the input arguments&quot;
  (concat (set-conditions arg1 arg2)
          [`(not-empty-diff? ~arg1 ~arg2)]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :union [[_ arg1 arg2]]
  &quot;Set union precondition predicate, it is only true if the last arg is the union of the input arguments&quot;
  (set-conditions arg1 arg2))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :intersection [[_ arg1 arg2]]
  &quot;Set intersection precondition predicate, it is only true if the last arg is the intersection of the input arguments&quot;
  (concat (set-conditions arg1 arg2)
          [`(not-empty-inter? ~arg1 ~arg2)]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :substitute-if-unifies
  [[_ arg1 arg2 arg3]]
  &quot;This predicate substitutes the for the unification of both arguments
   needed variable unification also in the conclusion.&quot;
  [`(munification-map ~arg1 ~arg2 ~arg3)])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :contains?
  [[_ arg1 arg2]]
  &quot;Whether the list arg1 contains the term arg2&quot;
  [`(some (set [~arg2]) ~arg1)])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def implications-and-equivalences
  (union implications equivalences))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :not-implication-or-equivalence
  [[_ arg]]
  &quot;This precondition predicate only returns true if the arg term is neither a type of implication
  nor a type of equivalence&quot;
  [`(if (coll? ~arg)
      (nil? (~`implications-and-equivalences (first ~arg)))
      true)])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn get-terms
  [st]
  &quot;Get all the statement sub-terms&quot;
  (if (coll? st)
    (mapcat get-terms (rest st))
    [st]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :no-common-subterm
  [[_ arg1 arg2]]
  &quot;Only true if no common subterm between both terms is shared&quot;
  [`(empty? (intersection (set (get-terms ~arg1))
                          (set (get-terms ~arg2))))])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :not-set?
  [[_ arg]]
  &quot;Only true if the term in question is not a set term.&quot;
  [`(or (not (coll? ~arg)) (not (sets (first ~arg))))])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :measure-time
  [_]
  &quot;Measures the time between both premises, where task has to have the newer occurrence time and both arguments are non-eternal&quot;
  [`(not= :eternal :t-occurrence)
   `(not= :eternal :b-occurrence)
   `(&lt; :b-occurrence :t-occurrence)
   #_`(&lt;= ~temporal-window-duration (abs (- :t-occurrence :b-occurrence)))])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :measure-time-backward
  [_]
  &quot;Measures the time between both premises, but this time belief is the newer task in terms of occurrence time.&quot;
  [`(not= :eternal :t-occurrence)
   `(not= :eternal :b-occurrence)
   `(&gt; :b-occurrence :t-occurrence)
   #_`(&lt;= ~temporal-window-duration (abs (- :t-occurrence :b-occurrence)))])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod compound-precondition :concurrent
  [_]
  &quot;Only true when both premises happen below temporal-window-duration away from each other.&quot;
  [`(not= :eternal :t-occurrence)
   `(not= :eternal :b-occurrence)
   `(&gt; ~temporal-window-duration (abs (- :t-occurrence :b-occurrence)))])</pre></td></tr><tr><td class="docs"><h2></h2>
</td><td class="codes"><pre class="brush: clojure">(defmulti precondition-transformation (fn [arg1 _] (first arg1)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod precondition-transformation :default [_ conclusion] conclusion)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn sets-transformation
  [[cond-name el1 el2 el3] conclusion]
  (walk conclusion (= :el el3)
    `(~(f-map cond-name) ~el1 ~el2)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(doall (map
         #(defmethod precondition-transformation %
           [cond concl] (sets-transformation cond concl))
         [:difference :union :intersection]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod precondition-transformation :substitute
  [[_ el1 el2] conclusion]
  &quot;This precondition predicate is only true if the conclusion has all occurrences of el1 replaced with el2&quot;
  `(walk ~conclusion
     (= :el ~el1) ~el2))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod precondition-transformation :substitute-from-list
  [[_ el1 el2] conclusion]
  &quot;Allows to substitute a certain element in the term list with another value, needed for elegant NAL4 rule specification&quot;
  `(mapv (fn [k#]
           (if (= k# ~el1)
             k#
             (walk k# (= :el ~el1) ~el2 :single-level-hack)))
         ~conclusion))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod precondition-transformation :substitute-if-unifies
  [[_ p1 p2 p3] conclusion]
  `(substitute ~p1 ~p2 ~p3 ~conclusion))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod precondition-transformation :measure-time
  [[_ arg] conclusion]
  (let [mt (gensym)]
    (walk `(let [~arg (abs (- :t-occurrence :b-occurrence))]
             ~(walk conclusion
                (= :el arg) [:interval arg]))
      (= :el arg) mt)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod precondition-transformation :measure-time-backward
  [[_ arg] conclusion]
  (let [mt (gensym)]
    (walk `(let [~arg (abs (- :t-occurrence :b-occurrence))]
             ~(walk conclusion
                    (= :el arg) [:interval arg]))
          (= :el arg) mt)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn check-precondition
  [conclusion precondition]
  (if (seq? precondition)
    (precondition-transformation precondition conclusion)
    conclusion))</pre></td></tr><tr><td class="docs"><p>Some transformations of conclusion may be required by precondition.</p>
</td><td class="codes"><pre class="brush: clojure">(defn preconditions-transformations
  [conclusion preconditions]
  (reduce check-precondition conclusion preconditions))</pre></td></tr><tr><td class="docs"><h2></h2>
</td><td class="codes"><pre class="brush: clojure">(defmulti conclusion-transformation (fn [arg1 _] (first arg1)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn shift-forward-let
  ([sym conclusion] (shift-forward-let sym nil conclusion nil))
  ([sym op conclusion temporal-window-duration]
   `(let [interval# ~sym
          ~@(if temporal-window-duration
              `[:t-occurrence (~op :t-occurrence ~temporal-window-duration)]
              [])
          :t-occurrence (if interval# (+ :t-occurrence interval#)
                                      :t-occurrence)]
      ~conclusion)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod conclusion-transformation :shift-occurrence-forward
  [args concl]
  (m/match (mapv #(if (and (coll? %) (= 'quote (first %)))
                   (second %) %) (rest args))
    [(:or '=|&gt; '==&gt;)] concl
    ['pred-impl] `(let [:t-occurrence (+ :t-occurrence ~temporal-window-duration)] ~concl)
    ['retro-impl] `(let [:t-occurrence (- :t-occurrence ~temporal-window-duration)] ~concl)
    [sym (:or '=|&gt; '==&gt;)] (shift-forward-let sym concl)
    [sym 'pred-impl] (shift-forward-let sym `+ concl temporal-window-duration)
    [sym 'retro-impl] (shift-forward-let sym `- concl temporal-window-duration)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn backward-interval-check [sym]
  `(and (coll? ~sym) (= (first ~sym) (quote ~'seq-conj))
        (let [cnt# (count ~sym)]
          (and (odd? cnt#) (get-in ~sym [(dec cnt#) 1])))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn shift-backward-let
  ([sym conclusion] (shift-backward-let sym nil conclusion nil))
  ([sym op conclusion temporal-window-duration]
   `(let [interval# ~(backward-interval-check sym)
          ~@(if temporal-window-duration
              `[:t-occurrence (~op :t-occurrence ~temporal-window-duration)]
              [])
          :t-occurrence (if interval# (+ :t-occurrence interval#)
                                      :t-occurrence)]
      (if interval#
        (update ~conclusion :statement reduce-seq-conj)
        ~conclusion))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod conclusion-transformation :shift-occurrence-backward
  [args concl]
  &quot;Shifts the occurrence time of the conclusion by the specified time offset.&quot;
  (let [temporal-window-duration (- temporal-window-duration)]
    (m/match (mapv #(if (and (coll? %) (= 'quote (first %)))
                     (second %) %) (rest args))
      [(:or '=|&gt; '==&gt;)] concl
      ['pred-impl] `(let [:t-occurrence (+ :t-occurrence ~temporal-window-duration)] ~concl)
      ['retro-impl] `(let [:t-occurrence (- :t-occurrence ~temporal-window-duration)] ~concl)
      [sym (:or '=|&gt; '==&gt;)] (shift-backward-let sym concl)
      [sym 'pred-impl] (shift-backward-let sym `+ concl temporal-window-duration)
      [sym 'retro-impl] (shift-backward-let sym `- concl temporal-window-duration))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.premises-swapping" name="nal.deriver.premises-swapping"><h1 class="project-name">nal.deriver.premises-swapping</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.premises-swapping
  (:require [nal.deriver.key-path :refer [rule-path]]
            [nal.deriver.normalization :refer [commutative-ops]]))</pre></td></tr><tr><td class="docs"><p>the set of keys which prevent premises swapping for rule</p>
</td><td class="codes"><pre class="brush: clojure">(def anti-swapping-keys
  #{:question? :belief? :goal? :measure-time :t/belief-structural-deduction
    :t/structural-deduction :t/belief-structural-difference :t/identity
    :t/negation :union :intersection :t/intersection :t/union})</pre></td></tr><tr><td class="docs"><p>Checks if rule allow swapping of premises.</p>
</td><td class="codes"><pre class="brush: clojure">(defn allow-swapping?
  [{:keys [pre conclusions]}]
  (let [{:keys [post conclusion]} (first conclusions)]
    (not-any? anti-swapping-keys (flatten (concat pre post)))))</pre></td></tr><tr><td class="docs"><p>Swaps the premises and truth function arguments to have symmetric rules being able to be used both ways.</p>
</td><td class="codes"><pre class="brush: clojure">(defn swap-premises
  [{:keys [p1 p2] :as rule}]
  (let [premise-swapped (assoc rule :p1 p2
                                    :p2 p1
                                    :full-path (rule-path p2 p1))]
    (assoc premise-swapped
      :conclusions
      (for [c (:conclusions premise-swapped)]
        (assoc (assoc c                                    
                 :post
                 (conj (:post c) :truth-swapped))           ;since the second premise is a belief always,
          :pre (conj (:pre c) :belief?))))))                ;the task after swapping is a belief always too</pre></td></tr><tr><td class="docs"><p>the task after swapping is a belief always too</p>
</td><td class="codes"></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn swap [rule] [rule (swap-premises rule)])</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.projection-eternalization" name="nal.deriver.projection-eternalization"><h1 class="project-name">nal.deriver.projection-eternalization</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.projection-eternalization
  (:require
    [nal.deriver.truth :refer [w2c frequency confidence]]))</pre></td></tr><tr><td class="docs"><p>projects the task t to the target-time given the current time cur-time.</p>

<p>temporally project task to ref task (note: this is only for event tasks!!)"</p>
</td><td class="codes"><pre class="brush: clojure">(defn project-to
  [target-time t cur-time]
  (when (= :eternal (:occurrence t))
    (println &quot;ERROR: Project called on eternal task!!&quot;))
  (let [source-time (:occurrence t)
        dist (fn [a b] (Math/abs (- a b)))
        a 10.0]
    (if (= target-time source-time)
      t
      (assoc t
       :truth [(frequency t)
               (* (confidence t)
                  (- 1 (/ (dist source-time target-time)
                          (+ (dist source-time cur-time)
                             (dist target-time cur-time)
                             a))))]
       :occurrence target-time))))</pre></td></tr><tr><td class="docs"><p>Eternalizes the task t</p>

<p>eternalize an event task to a task of eternal occurrence time</p>
</td><td class="codes"><pre class="brush: clojure">(defn eternalize
  [t]
  (when (= (:occurrence t) :eternal)
    (println &quot;error: eternalization on eternal task&quot;))
  (if (or (= (:task-type t) :belief) (= (:task-type t) :goal))
    (assoc t :truth [(frequency t) (w2c (confidence t))]
            :occurrence :eternal)
    (assoc t :occurrence :eternal)))</pre></td></tr><tr><td class="docs"><p>Task t is projected or eternalized to target-time dependent on the occurrence type of target-time.</p>

<p>temporally projecting/eternalizing a task to ref time</p>
</td><td class="codes"><pre class="brush: clojure">(defn project-eternalize-to
  [target-time t cur-time]
  (if (= nil t)
    nil
    (let [source-time (:occurrence t)
         get-eternal (fn [x] (if (= x :eternal) :eternal :temporal))]
     (case [(get-eternal target-time) (get-eternal source-time)]
       [:eternal :eternal] t
       [:temporal :eternal] (assoc t :occurrence target-time)
       [:eternal :temporal] (eternalize t)
       [:temporal :temporal] (project-to target-time t cur-time) #_(let [t-eternal (eternalize t)
                                   t-project (project-to target-time t cur-time)]
                               (if (&gt; (confidence t-eternal)
                                      (confidence t-project))
                                 (assoc t-eternal :occurrence target-time)
                                 t-project))))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.rules" name="nal.deriver.rules"><h1 class="project-name">nal.deriver.rules</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.rules
  (:require [clojure.string :as s]
            [clojure.set :refer [map-invert]]
            [nal.deriver
             [key-path :refer [rule-path all-paths path-invariants path]]
             [utils :refer [walk]]
             [list-expansion :refer [contains-list? generate-all-lists]]
             [premises-swapping :refer [allow-swapping? swap]]
             [matching :refer [generate-matching]]
             [backward-rules :refer [allow-backward? expand-backward-rules]]
             [normalization :refer [infix-&gt;prefix replace-negation]]
             [terms-permutation :refer [order-for-all-same? generate-all-orders]]]))</pre></td></tr><tr><td class="docs"><p>Generates map from rest of the rule's args.</p>
</td><td class="codes"><pre class="brush: clojure">(defn options
  [args]
  (when (seq args)
    (into {} (map vec (partition 2 args)))))</pre></td></tr><tr><td class="docs"><p>Parses conclusions from the rule.</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-conclusions
  [c opts]
  (if (and (seq? c) (some #{:post} c))
    (map (fn [[c _ post]] {:conclusion c :post post}) (partition 3 c))
    [{:conclusion c :post (:post opts)}]))</pre></td></tr><tr><td class="docs"><p>Generates rule from #R statement.</p>
</td><td class="codes"><pre class="brush: clojure">(defn rule
  [data]
  (let [[p1 p2 _ c &amp; other] (replace-negation data)]
    (let [p1 (infix-&gt;prefix p1)
          p2 (infix-&gt;prefix p2)
          c (infix-&gt;prefix c)
          opts (options other)
          conclusions (get-conclusions c opts)]
      (map (fn [c]
             {:p1          p1
              :p2          p2
              :conclusions [c]
              :full-path   (rule-path p1 p2)
              :pre         (infix-&gt;prefix (:pre opts))})
           conclusions))))</pre></td></tr><tr><td class="docs"><p>Checks if there are rules with same premises and preconditions but with
  different conclusions, merges them if they exist.</p>
</td><td class="codes"><pre class="brush: clojure">(defn check-duplication
  [rules]
  (vals (reduce (fn [ac {:keys [p1 p2 pre conclusions] :as r}]
                  (let [k [p1 p2 pre]]
                    (if (ac k)
                      (update-in ac [k :conclusions] concat conclusions)
                      (assoc ac k r))))
                {} rules)))</pre></td></tr><tr><td class="docs"><p>Return true if rule allows only question as task.</p>
</td><td class="codes"><pre class="brush: clojure">(defn question?
  [{:keys [pre] [{post :post}] :conclusions}]
  (some #{:question?} pre))                                ;all rules that allow backward can be used for question generation</pre></td></tr><tr><td class="docs"><p>all rules that allow backward can be used for question generation</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>Return true if rule allows only quest as task.</p>
</td><td class="codes"><pre class="brush: clojure">(defn quest?
  [{:keys [pre] [{post :post}] :conclusions}]
  (some #{:question?} pre))                                ;all rules that allow backward can be used for quests and goals</pre></td></tr><tr><td class="docs"><p>all rules that allow backward can be used for quests and goals</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>Return true if rule allows only goal as task.</p>
</td><td class="codes"><pre class="brush: clojure">(defn goal?
  [{pre :pre [{post :post}] :conclusions}]
  (and (not (some #{:belief?} pre))                         ;these which don't want a question or belief
       (not (some #{:question?} pre))))                     ;can also be used for goal tasks</pre></td></tr><tr><td class="docs"><p>can also be used for goal tasks</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>Return true if rule allows only belief as task.</p>
</td><td class="codes"><pre class="brush: clojure">(defn belief?
  [{:keys [pre] :as rule}]
  (and (not (some #{:goal?} pre))                          ;these which don't want a question or goal
       (not (some #{:question?} pre))))                    ;can also be used for belief tasks</pre></td></tr><tr><td class="docs"><p>can also be used for belief tasks</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>Selects all rules that will match the same path as current rule and adds
  these rules to the set of rules that matches path.
  For instance:
  current rule's path [[--> [- :any :any] :any] :and [--> [:any :any]]]</p>

<p>  so, if we find rule with path [[--> :any :any] :and [--> [:any :any]]],
  it matches to current's rule path too, hence it should be added to the set
  of rules that matches [[--> [- :any :any] :any] :and [--> [:any :any]]] path.</p>
</td><td class="codes"><pre class="brush: clojure">(defn add-possible-paths
  [ac [k {:keys [all]}]]
  (let [rules (mapcat :rules (vals (select-keys ac all)))]
    (-&gt; ac
        (update-in [k :rules] concat rules)
        (update-in [k :rules] set))))</pre></td></tr><tr><td class="docs"><p>Adds rule to map of rules, conjoin rule to set of rules that
  matches to pattern. Rules paths are keys in this map.</p>
</td><td class="codes"><pre class="brush: clojure">(defn rule-&gt;map
  [ac {:keys [p1 p2 full-path] :as rule}]
  (-&gt; ac
      (update-in [full-path :rules] conj rule)
      (assoc-in [full-path :pattern] [p1 p2])
      (assoc-in [full-path :all] (all-paths (path p1) (path p2)))
      (assoc-in [full-path :starts-with] (set (path-invariants p1)))
      (assoc-in [full-path :end-with] (set (path-invariants p2)))))</pre></td></tr><tr><td class="docs"><p>Generates map from list of #R satetments, whetre key is path, and value is
  another map with keys pattern ans rules. Pattern is will be used to match
  values from the premises, rules will be used to generate deriver.</p>
</td><td class="codes"><pre class="brush: clojure">(defn rules-map
  [ruleset task-type]
  (let [rules (reduce rule-&gt;map {} ruleset)]
    (generate-matching rules task-type)))</pre></td></tr><tr><td class="docs"><hr />
</td><td class="codes"></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmacro rules-&gt;&gt; [raw-rules &amp; transformations]
  (let [pairs (partition 2 transformations)]
    (reduce (fn [code [pred fun]]
              `(mapcat (fn [rule#]
                         (if (~pred rule#)
                           (~fun rule#)
                           [rule#]))
                       ~code))
            `~raw-rules
            pairs)))</pre></td></tr><tr><td class="docs"><p>Define rules. Rules must be #R statements.</p>
</td><td class="codes"><pre class="brush: clojure">(defmacro defrules
  [name first &amp; rules]
  (let [rules (if (string? first) rules (cons first rules))]
    `(def ~name (quote ~rules))))</pre></td></tr><tr><td class="docs"><p>Define rules. Rules must be #R statements.</p>
</td><td class="codes"><pre class="brush: clojure">(defn compile-rules
  ;TODO exception on duplication of the rule
  [&amp; rules]
  (time
    (let [rules (rules-&gt;&gt; (apply concat rules)
                          contains-list? generate-all-lists
                          contains-list? generate-all-lists
                          identity rule
                          order-for-all-same? generate-all-orders
                          allow-swapping? swap
                          allow-backward? expand-backward-rules)
          belief-rules# (check-duplication (filter belief? rules))
          question-rules# (check-duplication (filter question? rules))
          goal-rules# (check-duplication (filter goal? rules))
          quest-rules# (check-duplication (filter quest? rules))]
      (println &quot;Beliefs rules:&quot; (count belief-rules#))
      (println &quot;Questions rules:&quot; (count question-rules#))
      (println &quot;Goal rules:&quot; (count goal-rules#))
      (println &quot;Quests rules:&quot; (count quest-rules#))
      {:belief (rules-map belief-rules# :belief)
       :question  (rules-map question-rules# :question)
       :goal      (rules-map goal-rules# :goal)
       :quest     (rules-map quest-rules# :quest)})))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.set-functions" name="nal.deriver.set-functions"><h1 class="project-name">nal.deriver.set-functions</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.set-functions
  (:require [clojure.set :as set]))</pre></td></tr><tr><td class="docs"><p>Set difference precondition operation application code</p>

<p>todo performance</p>
</td><td class="codes"><pre class="brush: clojure">(defn difference
  [[op &amp; set1] [_ &amp; set2]]
  (into [op] (sort-by hash (set/difference (set set1) (set set2)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn union [[op &amp; set1] [_ &amp; set2]]
  &quot;Set union precondition operation application code&quot;
  (into [op] (sort-by hash (set/union (set set1) (set set2)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn intersection [[op &amp; set1] [_ &amp; set2]]
  &quot;Set intersection precondition operation application code&quot;
  (into [op] (sort-by hash (set/intersection (set set1) (set set2)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def f-map {:difference   difference
            :union        union
            :intersection intersection})</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn not-empty-diff? [[_ &amp; set1] [_ &amp; set2]]
  (not-empty (set/difference (set set1) (set set2))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn not-empty-inter? [[_ &amp; set1] [_ &amp; set2]]
  (not-empty (set/intersection (set set1) (set set2))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.substitution" name="nal.deriver.substitution"><h1 class="project-name">nal.deriver.substitution</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.substitution
  (:require [nal.deriver.utils :refer [walk]]
            [clojure.core.unify :as u]
            [clojure.core.memoize :refer [lru]]
            [clojure.string :as s]))</pre></td></tr><tr><td class="docs"><p>Defn replaces var-elements from statemts by placeholders for unification.</p>
</td><td class="codes"><pre class="brush: clojure">(defn replace-vars
  [var-type statement]
  (walk statement
    (and (coll? :el) (= var-type (first :el)))
    (-&gt;&gt; :el second (str &quot;?&quot;) symbol)))</pre></td></tr><tr><td class="docs"><p>Returns map of inified elements from both collections.</p>
</td><td class="codes"><pre class="brush: clojure">(defn unification-map
  [var-symbol p2 p3]
  (let [[mode check-var-type] (if (= var-symbol &quot;$&quot;)                ;in this cases also dependent var
                                [:ind #(or (= % 'ind-var) (= % 'dep-var))] ;elimination is fine!
                                [:dep #(= % 'dep-var)])
        result ((u/make-occurs-unify-fn #(and (coll? %) (check-var-type (first %)))) p2 p3)]
    (if (= mode :ind)
      result
      (if (and result
               (&gt; (count result) 0))
        result
        nil)))) ;we dont allow dependent variable unification if there is no dependent var</pre></td></tr><tr><td class="docs"><p>we dont allow dependent variable unification if there is no dependent var
this reduces the amount of conclusions which would be weaker and interferre.</p>
</td><td class="codes"></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">#_(def munification-map (memoize unification-map))
(def munification-map (lru unification-map :lru/threshold 50))
#_(def munification-map unification-map)
(defn placeholder-&gt;symbol [pl]
  (-&gt;&gt; pl str (drop 1) s/join symbol))</pre></td></tr><tr><td class="docs"><p>Updates keys in unification map from placeholders like ?X to vectors like
  ['dep-var X]</p>
</td><td class="codes"><pre class="brush: clojure">(defn replace-placeholders
  [var-type u-map]
  (-&gt;&gt; u-map
       (map (fn [[k v]] [[var-type (placeholder-&gt;symbol k)] v]))
       (into {})))</pre></td></tr><tr><td class="docs"><p>Unifies p2 and p3, then replaces elements from the unification map
  inside the conclusion.</p>
</td><td class="codes"><pre class="brush: clojure">(defn substitute
  [var-symbol p2 p3 conclusion]
  (let [u-map (munification-map var-symbol p2 p3)]
    (walk conclusion (u-map el) (u-map el))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.terms-permutation" name="nal.deriver.terms-permutation"><h1 class="project-name">nal.deriver.terms-permutation</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.terms-permutation
  (:require [nal.deriver.utils :refer [walk]]))</pre></td></tr><tr><td class="docs"><p>Checks if statement contains operators from set.</p>
</td><td class="codes"><pre class="brush: clojure">(defn contains-op?
  [statement s]
  (cond
    (symbol? statement) (s statement)
    (or (keyword? statement)
        (char? statement)
        (string? statement)
        (number? statement)) false
    :default (some identity (map #(contains-op? % s) statement))))</pre></td></tr><tr><td class="docs"><p>Replaces operator "from" by operator "to"</p>
</td><td class="codes"><pre class="brush: clojure">(defn replace-op
  [statement from to]
  (walk statement (= from el) to))</pre></td></tr><tr><td class="docs"><p>Makes permuatation of operators from s in statement.</p>
</td><td class="codes"><pre class="brush: clojure">(defn permute-op
  [statement s]
  (if-let [op (contains-op? statement s)]
    (map #(replace-op statement op %) s)
    [statement]))</pre></td></tr><tr><td class="docs"><p>equivalences, implications, conjunctions - sets of operators that are use in
permutation for :order-for-all-same postcondititon</p>
</td><td class="codes"><pre class="brush: clojure">(def equivalences #{'&lt;=&gt; '&lt;/&gt; '&lt;|&gt;})
(def implications #{'==&gt; 'pred-impl '=|&gt; 'retro-impl})
(def conjunctions #{'conj '&amp;| 'seq-conj})</pre></td></tr><tr><td class="docs"><p>Permutes all operators in statement with :order-for-all-same precondition.</p>
</td><td class="codes"><pre class="brush: clojure">(defn generate-all-orders
  [{:keys [p1 p2 conclusions full-path pre] :as rule}]
  (let [{:keys [conclusion] :as c1} (first conclusions)
        statements (-&gt;&gt; (permute-op [p1 p2 conclusion full-path pre] equivalences)
                        (mapcat (fn [st] (permute-op st conjunctions)))
                        (mapcat (fn [st] (permute-op st implications)))
                        set)]
    (map (fn [[p1 p2 c full-path pre]]
           (assoc rule :p1 p1
                       :p2 p2
                       :full-path full-path
                       :conclusions [(assoc c1 :conclusion c)]
                       :pre pre))
         statements)))</pre></td></tr><tr><td class="docs"><p>Return true if rule contains order-for-all-same postcondition</p>
</td><td class="codes"><pre class="brush: clojure">(defn order-for-all-same?
  [{:keys [conclusions]}]
  (some #{:order-for-all-same} (:post (first conclusions))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.truth" name="nal.deriver.truth"><h1 class="project-name">nal.deriver.truth</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.truth
  (:require [narjure.defaults :refer [horizon] :as d]))</pre></td></tr><tr><td class="docs"><p>https://github.com/opennars/opennars/blob/6611ee7f0b1428676b01ae4a382241a77ae3a346/nars_logic/src/main/java/nars/nal/meta/BeliefFunction.java
https://github.com/opennars/opennars/blob/7b27dacec4cdbe77ca03d89296323d49875ac213/nars_logic/src/main/java/nars/truth/TruthFunctions.java</p>
</td><td class="codes"></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn t-and
  (^double [^double a ^double b] (* a b))
  (^double [^double a ^double b ^double c] (* a b c))
  (^double [^double a ^double b ^double c ^double d] (* a b c d)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn t-or
  (^double [^double a ^double b] (- 1 (* (- 1 a) (- 1 b)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn w2c ^double [^double w]
  (let [^double h horizon] (/ w (+ w h))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn c2w ^double [^double c]
  (let [^double h horizon] (/ (* h c) (- 1 c))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn t2-evidence-weights [[f c]]
  (let [total-evidence (c2w c)
        positive-evidence (* f total-evidence)
        negative-evidence (- total-evidence positive-evidence)]
  {:negative-evidence negative-evidence
   :positive-evidence positive-evidence
   :total-evidence total-evidence }))                                        ;not used by deriver, just by anticipations</pre></td></tr><tr><td class="docs"><p>not used by deriver, just by anticipations</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none">Truth formula</a></p>

<h2></h2>
</td><td class="codes"><pre class="brush: clojure">(defn conversion
  [_ p1]
  (when-let [[f c] p1] [1 (w2c (and f c))]))</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none">Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn negation
  [[^double f ^double c] _] [(- 1 f) c])</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none"Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn contraposition
  [[^double f ^double c]  [^double f2 ^double c2]]
  [0 (w2c (and (- 1 f) c))])</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none"Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn revision
  [[^double f1 ^double c1] [^double f2 ^double c2]]
  (let [w1 (c2w c1)
        w2 (c2w c2)
        w (+ w1 w2)]
    [(/ (+ (* w1 f1) (* w2 f2)) w) (w2c w)]))</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none"Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn deduction
  [[^double f1 ^double c1] [^double f2 ^double c2]]
  (let [f (t-and f1 f2)]
    [f (t-and f c1 c2)]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn a-deduction [[^double f1 ^double c1] c2] [f1 (t-and f1 c1 c2)])</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none"Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn analogy
  [[^double f1 ^double c1] [^double f2 ^double c2]]
  [(t-and f1 f2) (t-and c1 c2 f2)])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn desire-strong [a b]
  (analogy a b))</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none"Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn resemblance
  [[^double f1 ^double c1] [^double f2 ^double c2]]
  [(t-and f1 f2) (t-and c1 c2 (t-or f1 f2))])</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none"Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn abduction
  [[^double f1 ^double c1] [^double f2 ^double c2]]
  [f1 (w2c (t-and f2 c1 c2))])</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none"Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn induction
  [p1 p2]
  (abduction p2 p1))</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none"Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn exemplification
  [[^double f1 ^double c1] [^double f2 ^double c2]]
  [1 (w2c (t-and f1 f2 c1 c2))])</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none"Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn comparison
  [[^double f1 ^double c1] [^double f2 ^double c2]]
  (let [f0 (t-or f1 f2)
        f (if (zero? f0) 0 (/ (t-and f1 f2) f0))
        c (w2c (t-and f0 c1 c2))]
    [f c]))</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none"Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn union
  [[^double f1 ^double c1] [^double f2 ^double c2]]
  [(t-or f1 f2) (t-and c1 c2)])</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none"Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn intersection
  [[^double f1 ^double c1] [^double f2 ^double c2]]
  [(t-and f1 f2) (t-and c1 c2)])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn anonymous-analogy [[^double f1 ^double c1] p2] (analogy p2 [f1 (w2c c1)]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn decompose-pnn [[^double f1 ^double c1] p2]
  (when p2
    (let [[^double f2 ^double c2] p2
          fn (t-and f1 (- 1 f2))]
      [(- 1 fn) (t-and fn c1 c2)])))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn decompose-npp [[^double f1 ^double c1] p2]
  (when p2
    (let [[^double f2 ^double c2] p2
          f (t-and (- 1 f1) f2)]
      [f (t-and f c1 c2)])))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn decompose-pnp [[^double f1 ^double c1] p2]
  (when p2
    (let [[^double f2 ^double c2] p2
          f (t-and f1 (- 1 f2))]
      [f (t-and f c1 c2)])))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn decompose-ppp [p1 p2] (decompose-npp (negation p1 p2) p2))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn decompose-nnn [[^double f1 ^double c1] p2]
  (when p2
    (let [[^double f2 ^double c2] p2
          fn (t-and (- 1 f1) (- 1 f2))]
      [(- 1 fn) (t-and fn c1 c2)])))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn difference [[^double f1 ^double c1] [^double f2 ^double c2]]
  [(t-and f1 (- 1 f2)) (t-and c1 c2)])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn structual-intersection [_ p2] (deduction p2 [1 d/belief-confidence]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn structual-deduction [p1 _] (deduction p1 [1 d/belief-confidence]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn structual-abduction [_ p2] (abduction p2 [1 d/belief-confidence]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn reduce-conjunction [p1 p2]
  (-&gt; (negation p1 p2)
      (intersection p2)
      (a-deduction 1)
      (negation p2)))</pre></td></tr><tr><td class="docs"><p>Peis email: Confidence</p>
</td><td class="codes"><pre class="brush: clojure">(defn t-identity [p1 _] [(first p1) (* (second p1) d/belief-confidence)])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn d-identity [p1 _] [(first p1) (* (second p1) d/belief-confidence)])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn belief-identity [_ p2] [(first p2) (* (second p2) d/belief-confidence)])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn belief-structural-deduction [_ p2]
  (when p2 (deduction p2 [1 d/belief-confidence])))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn belief-structural-difference [_ p2]
  (when p2
    (let [[^double f ^double c] (deduction p2 [1 d/belief-confidence])]
      [(- 1 f) c])))</pre></td></tr><tr><td class="docs"><p><a href="NAL-Specification.pdf#page=90" style="text-decoration:none"Truth formula</a></p>
</td><td class="codes"><pre class="brush: clojure">(defn belief-negation
  [_ p2]
  (when p2 (negation p2 nil)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn desire-weak [[f1 c1] [f2 c2]]
  [(t-and f1 f2) (t-and c1 c2 f2 (w2c 1.0))])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn desire-induction
  [[f1 c1] [f2 c2]]
  [f1 (w2c (t-and f2 c1 c2))])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn desire-structural-strong
  [t _]
  (analogy t [1.0 d/belief-confidence]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn expectation [t]
  (+ (* (second t) (- (first t) 0.5)) 0.5))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn confidence [t]
  (second (:truth t)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn frequency [t]
  (first (:truth t)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def tvtypes
  {:t/structural-deduction         structual-deduction
   :t/struct-int                   structual-intersection
   :t/struct-abd                   structual-abduction
   :t/identity                     t-identity
   :t/conversion                   conversion
   :t/contraposition               contraposition
   :t/negation                     negation
   :t/comparison                   comparison
   :t/intersection                 intersection
   :t/union                        union
   :t/difference                   difference
   :t/decompose-ppp                decompose-ppp
   :t/decompose-pnn                decompose-pnn
   :t/decompose-nnn                decompose-nnn
   :t/decompose-npp                decompose-npp
   :t/decompose-pnp                decompose-pnp
   :t/induction                    induction
   :t/abduction                    abduction
   :t/deduction                    deduction
   :t/exemplification              exemplification
   :t/analogy                      analogy
   :t/resemblance                  resemblance
   :t/anonymous-analogy            anonymous-analogy
   :t/belief-identity              belief-identity
   :t/belief-structural-deduction  belief-structural-deduction
   :t/belief-structural-difference belief-structural-difference
   :t/belief-negation              belief-negation
   :t/reduce-conjunction           reduce-conjunction})</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def dvtypes
  {:d/strong            analogy
   :d/deduction         intersection
   :d/weak              desire-weak
   :d/induction         desire-induction
   :d/identity          d-identity
   :d/negation          negation
   :d/structural-strong desire-structural-strong})</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver.utils" name="nal.deriver.utils"><h1 class="project-name">nal.deriver.utils</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver.utils
  (:require [clojure.walk :as w]))</pre></td></tr><tr><td class="docs"><p>Checks if element is not operator</p>
</td><td class="codes"><pre class="brush: clojure">(defn not-operator?
  [el] (re-matches #&quot;[akxA-Z$]&quot; (-&gt; el str first str)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def operator? (complement not-operator?))</pre></td></tr><tr><td class="docs"><p>Clojure postwalk but with depth 1 only as demanded by NAL4 rules</p>
</td><td class="codes"><pre class="brush: clojure">(defn postwalk-depth1
  ([f form]
   (postwalk-depth1 f 0 form))
  ([f depth form]
   (if (&gt; depth 1)
     (w/walk (partial postwalk-depth1 identity (inc depth)) identity form)
     (w/walk (partial postwalk-depth1 f (inc depth)) f form))))</pre></td></tr><tr><td class="docs"><p>Macro that helps to replace elements during walk. The first argument
  is collection, rest of the arguments are cond-like
  expressions. Default result of cond is element itself.
  el (optionally :el) is reserved name for current element of collection.</p>
</td><td class="codes"><pre class="brush: clojure">(defmacro walk
  ([coll &amp; conditions]
   (let [el (gensym)
         replace-el (fn [coll]
                      (w/postwalk #(if (or (= 'el %) (= :el %)) el %) coll))]
     `(~(if (= (last conditions) :single-level-hack)
         postwalk-depth1
         w/postwalk)
        (fn [~el] (cond ~@(replace-el (if (= (last conditions) :single-level-hack) (drop-last conditions) conditions))
                        :else ~el))
        ~coll))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.deriver" name="nal.deriver"><h1 class="project-name">nal.deriver</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.deriver
  (:require
    [nal.deriver.utils :refer [walk]]
    [nal.deriver.key-path :refer [mall-paths all-paths mpath-invariants
                                  path-with-max-level]]
    [nal.deriver.rules :refer [rule]]
    [nal.deriver.normalization :refer [commutative-ops sort-commutative]]
    [clojure.set :as set]
    [nal.term_utils :refer :all]
    [clojure.core.memoize :refer [lru]]
    [nal.rules :as r]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn get-matcher [rules p1 p2]
  (let [matchers (-&gt;&gt; (mall-paths p1 p2)
                      (filter rules)
                      (map rules))]
    (case (count matchers)
      0 (constantly [])
      1 (first matchers)
      (fn [t1 t2] (mapcat #(% t1 t2) matchers)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">#_(def mget-matcher (memoize get-matcher))
(def mget-matcher (lru get-matcher :lru/threshold 50))
#_(def mget-matcher get-matcher)
#_(def mpath (memoize path-with-max-level))
(def mpath (lru path-with-max-level :lru/threshold 50))
#_(def mpath path-with-max-level)
(defn parallel-conj [term]
  (and (coll? term)
       (= (first term) '&amp;|)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn sequ-conj [term]
  (and (coll? term)
       (= (first term) 'seq-conj)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn parallel-conj-reduce [term layer]
  term
  (if (parallel-conj term)
    (let [reduced (apply concat
                         (for [x term]
                           (if (parallel-conj x)
                             (parallel-conj-reduce x (inc layer))
                             (if (= x '&amp;|)
                               []
                               [x]))))]
      (if (= layer 0)
        (vec (conj reduced '&amp;|))
        (vec reduced)))
    term))</pre></td></tr><tr><td class="docs"><p>generate conclusions not taking commutative subterms of premises into account</p>
</td><td class="codes"><pre class="brush: clojure">(defn generate-conclusions-no-commutativity
  [rules {p1 :statement :as t1} {p2 :statement :as t2}]
  (let [matcher (mget-matcher rules (mpath p1) (mpath p2))
        result (set (matcher t1 t2))]
    (for [z result]
      (assoc z :statement (sort-commutative (parallel-conj-reduce (:statement z) 0))))))</pre></td></tr><tr><td class="docs"><p>USE COUNTER (global seed, for making testcased deterministic</p>
</td><td class="codes"><pre class="brush: clojure">(def use-counter (ref 0))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn use-counter-reset []
  (do
    (dosync (ref-set use-counter 0))
    @use-counter))</pre></td></tr><tr><td class="docs"><p>Return a random permutation of coll with a seed</p>

<p>Adjusted shuffle given a seed, "shuffle-with-seed", from sloth:
http://stackoverflow.com/questions/24553212/how-to-take-n-random-items-from-a-collection-in-clojure
(since we don't want non-deterministic testcases)</p>
</td><td class="codes"><pre class="brush: clojure">(defn shuffle-random
  [coll]
  (dosync (commute use-counter inc)
          (let [seed (deref use-counter)
                al (java.util.ArrayList. coll)
                rnd (java.util.Random. (* seed 50000))]
            (java.util.Collections/shuffle al rnd)
            (clojure.lang.RT/vector (.toArray al)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn shuffle-term-one-layer [t]                            ;TODO put into term utils once merged with master
  (concat (list (first t)) (shuffle-random (rest t))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn shuffle-term [A]                                      ;TODO put into term utils once merged with master
  &quot;Shuffle a term recursively (all commutative subterms like (A &lt;-&gt; B)&quot;
  (let [shuffle? (fn [A] (and (coll? A)
                              (some #(= (first A) %) commutative-ops)))
        shuffled (if (shuffle? A)
                   (shuffle-term-one-layer A)
                   A)]
    (if (shuffle? A)
      (for [x shuffled]
        (shuffle-term x))
      A)))</pre></td></tr><tr><td class="docs"><p>Generate all conclusions between task t1 and task t2</p>
</td><td class="codes"><pre class="brush: clojure">(defn generate-conclusions
  [{p1_ :statement :as t1} {p2 :statement :as t2}]
  ;assign statement
  (let [p1 (if                                       ;ok the first one is eternal the second not, so lets use
             (and (= (:occurrence p1_) :eternal)     ;the occurence time of the second to not lose the temporal information (valid since it is eternal anyway)
                  (not= (:occurrence p2) :eternal))  ;this way eternalization is left to eternalization
             (assoc p1_ :occurrence (:occurrence p2)) ;note that we use the eternal belief also anyway currently
             p1_)                                     ;so the eternal case is not lost!!
        iterate-n (fn [next-it prev-shuffles prev-results x]
                    (let [shuffled-p1 (shuffle-term p1)
                          shuffled-p2 (shuffle-term p2)
                          shuffle-pair [shuffled-p1 shuffled-p2]
                          unification-power 5] ;how much shuffle attempts
                      (if (&lt; x unification-power)
                        (if (some #{shuffle} prev-shuffles)
                          (next-it next-it prev-shuffles prev-results (inc x)) ;generate-conclusions-no-commutativity is expensive this is why we avoid it
                          (let [new-results (set/union prev-results
                                                       (set (generate-conclusions-no-commutativity (r/rules (:task-type t1))
                                                                                                   (assoc t1 :statement shuffled-p1)
                                                                                                   (assoc t2 :statement shuffled-p2))))]
                            (next-it next-it (set/union prev-shuffles #{shuffle-pair}) (set/union prev-results new-results) (inc x))))
                        prev-results)))]
    (iterate-n iterate-n #{} #{} 0)))</pre></td></tr><tr><td class="docs"><p>Valid statement filter.
  The filter is a preliminary solution to get rid of statements that are not valid NAL statements.
  Some of these need detailled analysis and a lot of care / inference rule condition improvement to get rid of.</p>
</td><td class="codes"><pre class="brush: clojure">(defn valid-statement
   ;TODO extent
  [term]
  (and
    #_(coll? term)
    ;dont allow a. terms, only NAL statements are allowed (TODO discuss NAL9 name operator handling)
    #_(some #(= % (first term)) '[--&gt; &lt;-&gt; ==&gt; pred-impl retro-impl
                                =|&gt; &lt;=&gt; &lt;/&gt; &lt;|&gt;
                                -- || conj seq-conj &amp;|])
    ;temporal copula only allowed once
    (&lt;= (count (filter '#{==&gt; pred-impl retro-impl
                        =|&gt; &lt;=&gt; &lt;/&gt; &lt;|&gt;} (flatten term)))
       1)
    ;inheritance and Similarity can't have independent vars
    (not (and (coll? term)
              (some #(= % (first term)) '[--&gt; &lt;-&gt;])
              (some #(= % 'ind-var) (flatten term))))
    (not (and (coll? term)
              (= (count term) 3)
              (coll? (first term))
              (= 'seq-conj (first (first term)))
              (interval? (first (first term)))))
    (not-any? #(and (coll? term)
                    (= (count term) 3)
                    (= (first term) %)
                    (= (second term) (nth term 2)))
              '[--&gt; &lt;-&gt; ==&gt; pred-impl retro-impl =|&gt; &lt;=&gt; &lt;/&gt; &lt;|&gt;])))</pre></td></tr><tr><td class="docs"><p>Occurrence task of tasks, either :eternal or :event</p>
</td><td class="codes"><pre class="brush: clojure">(defn occurrence-type
  [occ]
  (case occ
    :eternal :eternal
    :event))</pre></td></tr><tr><td class="docs"><p>Inference between two premises</p>

<p>this is the inference function we should use</p>
</td><td class="codes"><pre class="brush: clojure">(defn inference
  [parsed-p1 parsed-p2]
  (set (map #(assoc % :statement
                      (apply-interval-precision (normalize-variables (:statement %))))
            (filter (fn [st] (and (or (= (:task-type st) :question)
                                      (= (:task-type st) :quest)
                                      (and (contains? st :truth)
                                           (coll? (:truth st))
                                           (&gt; (second (:truth st)) 0)))
                                  (valid-statement (:statement st))
                                  (not (and (= (:task-type st) :belief) ;TODO why happens at all?
                                            (some #{'qu-var} (flatten (:statement st)))))))
                    (map no-truth-for-questions-and-quests
                         (map interval-reduction
                              (generate-conclusions parsed-p1 parsed-p2)))))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.reader" name="nal.reader"><h1 class="project-name">nal.reader</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.reader
  (:require [clojure.string :as s])
  (:import (clojure.lang LispReader)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn dispatch-reader-macro [ch fun]
  (let [dm (.get
             (doto
               (.getDeclaredField LispReader &quot;dispatchMacros&quot;)
               (.setAccessible true))
             nil)]
    (aset dm (int ch) fun)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn fetch-rule
  ([rdr] (fetch-rule rdr  0))
  ([rdr prev cnt]
   (let [c (.read rdr)
         cnt (case (char c)
               \] (dec cnt)
               \[ (inc cnt)
               cnt)]
     (if (neg? cnt)
       prev
       (recur rdr (str prev (char c)) cnt)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn add-brackets [s]
  (str &quot;[&quot; s &quot;]&quot;))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn replacements [s]
  (-&gt; s
      (s/replace #&quot;\{([^\}]*)\}&quot; &quot;(ext-set $1)&quot;)
      (s/replace #&quot;\[([^\]]*)]&quot; &quot;(int-set $1)&quot;)
      (s/replace #&quot;=\\&gt;&quot; &quot;retro-impl&quot;)
      (s/replace #&quot;=/&gt;&quot; &quot;pred-impl&quot;)
      (s/replace #&quot;~&quot; &quot;int-dif&quot;)
      (s/replace #&quot;&amp;/&quot; &quot;seq-conj &quot;)
      (s/replace #&quot;\(&amp;\s&quot; &quot;(ext-inter &quot;)
      (s/replace #&quot;\s&amp;\s&quot; &quot; ext-inter &quot;)
      (s/replace #&quot;&amp;&amp;&quot; &quot;conj&quot;)
      (s/replace #&quot;\{--&quot; &quot;inst&quot;)
      (s/replace #&quot;--]&quot; &quot;prop&quot;)
      (s/replace #&quot;\{-\]&quot; &quot;inst-prop&quot;)
      (s/replace #&quot;\(\\&quot; &quot;(int-image&quot;)
      (s/replace #&quot;\(/&quot; &quot;(ext-image&quot;)
      (s/replace #&quot;\$([A-Z])&quot; &quot;(ind-var $1)&quot;)
      (s/replace #&quot;#([A-Z])&quot; &quot;(dep-var $1)&quot;)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn read-rule [s]
  (-&gt; s replacements add-brackets read-string))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn rule [rdr letter-R opts &amp; other]
  (let [c (.read rdr)]
    (if (= c (int \[))
      (read-rule (fetch-rule rdr))
      (throw (Exception. (str &quot;Reader barfed on &quot; (char c)))))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(dispatch-reader-macro \R rule)</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.rules" name="nal.rules"><h1 class="project-name">nal.rules</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.rules
  (:require [nal.deriver.rules :refer [defrules compile-rules]]
            nal.reader))</pre></td></tr><tr><td class="docs"><!-- <div style="z-index: 9999; position: fixed; left: 0; top: 0;"> <button <iframe name="bible" src="NAL-Specification.pdf" style="position:fixed" width=100% height=35%></iframe> </div> -->
</td><td class="codes"></td></tr><tr><td class="docs"><h1> Copulas </h1>

<p>--> is the <a href="NAL-Specification.pdf#page=11">Inheritance-relation</a>. A --> B describes that A is a special case of B. This relation thus makes it possible for the system to create a generalization-hierachy by using multiple statements. <br/>
&lt;-> is the <a href="NAL-Specification.pdf#page=29">Similarity-relation</a>. The Similarity-relation itself is defined as a bi-directional Inheritance-Relation.<br/>
==> is the <a href="NAL-Specification.pdf#page=46">Implication-relation</a> and naturally encodes the intiutive meaning of implication.<br/>
&amp;&amp; stands for <a href="NAL-Specification.pdf#page=46">Conjunction</a>, || for <a href="NAL-Specification.pdf#page=46">Disjunction</a>. More details can be seen in the relevant inference rule sections.</p>
</td><td class="codes"></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(declare --S S --P P &lt;-&gt; |- --&gt; ==&gt; M || &amp;&amp; =|&gt; -- A Ai B &lt;=&gt;)</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=87" style="text-decoration:none">NAL1 NAL2 NAL3 Equivalence and Implication Rules</a></h1><br/>  <!-- target="bible" -->
These rules are used to capture equivalence and implication theorems as described in the NAL reference.
Their correctness follows by the definitions of the NAL statement copulas.
Since the conclusion is equivalent, the truth value of the conclusion is using Identity as truth and desire function.
So these rules are for bringing NAL-statements into a different, implied and more appropriate form.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal1-nal2-nal3-equivalence-and-implication
          ;;Equivalence and Implication Rules
          ;Similarity to Inheritance
          #R[(S --&gt; P) (S &lt;-&gt; P) |- (S --&gt; P) :post (:t/struct-int :p/belief) :pre (:question?)]
          ;Inheritance to Similarity
          #R[(S &lt;-&gt; P) (S --&gt; P) |- (S &lt;-&gt; P) :post (:t/struct-abd :p/belief) :pre (:question?)]
          ;Set Definition Similarity to Inheritance
          #R[(S &lt;-&gt; {P}) S |- (S --&gt; {P}) :post (:t/identity :d/identity :allow-backward)]
          #R[(S &lt;-&gt; {P}) {P} |- (S --&gt; {P}) :post (:t/identity :d/identity :allow-backward)]
          #R[([S] &lt;-&gt; P) [S] |- ([S] --&gt; P) :post (:t/identity :d/identity :allow-backward)]
          #R[([S] &lt;-&gt; P) P |- ([S] --&gt; P) :post (:t/identity :d/identity :allow-backward)]
          #R[({S} &lt;-&gt; {P}) {S} |- ({P} --&gt; {S}) :post (:t/identity :d/identity :allow-backward)]
          #R[({S} &lt;-&gt; {P}) {P} |- ({P} --&gt; {S}) :post (:t/identity :d/identity :allow-backward)]
          #R[([S] &lt;-&gt; [P]) [S] |- ([P] --&gt; [S]) :post (:t/identity :d/identity :allow-backward)]
          #R[([S] &lt;-&gt; [P]) [P] |- ([P] --&gt; [S]) :post (:t/identity :d/identity :allow-backward)]
          ;Set Definition Unwrap
          #R[({S} &lt;-&gt; {P}) {S} |- (S &lt;-&gt; P) :post (:t/identity :d/identity :allow-backward)]
          #R[({S} &lt;-&gt; {P}) {P} |- (S &lt;-&gt; P) :post (:t/identity :d/identity :allow-backward)]
          #R[([S] &lt;-&gt; [P]) [S] |- (S &lt;-&gt; P) :post (:t/identity :d/identity :allow-backward)]
          #R[([S] &lt;-&gt; [P]) [P] |- (S &lt;-&gt; P) :post (:t/identity :d/identity :allow-backward)]
          ; Nothing is more specific than a instance so it's similar
          #R[(S --&gt; {P}) S |- (S &lt;-&gt; {P}) :post (:t/identity :d/identity :allow-backward)]
          #R[(S --&gt; {P}) {P} |- (S &lt;-&gt; {P}) :post (:t/identity :d/identity :allow-backward)]
          ; nothing is more general than a property so it's similar
          #R[([S] --&gt; P) [S] |- ([S] &lt;-&gt; P) :post (:t/identity :d/identity :allow-backward)]
          #R[([S] --&gt; P) P |- ([S] &lt;-&gt; P) :post (:t/identity :d/identity :allow-backward)])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=52" style="text-decoration:none">NAL1 NAL5 Conversion, Contraposition, Negation</a></h1><br/> <!-- target="bible" -->
          In term logics, "conversion" is an inference from a single premise to a conclusion by interchanging the subject
          and predicate terms of the premise. How the truth value is calculated can be seen in
          <a href="NAL-Specification.pdf#page=25">Conversion</a><br/><br/>
          In logic, contraposition is a law that says that a conditional statement is logically equivalent to its contrapositive.
          In NAL however it is not equivalent, click <a href="NAL-Specification.pdf#page=52">Contraposition</a> to see more detail about this.
          The contrapositive of the statement has its antecedent and consequent inverted and flipped.<br/><br/>
          <a href="NAL-Specification.pdf#page=50">Negation</a> just inverts the truth of a statement,
          which means, due to the semantics of the frequency, that the truth value can be directly obtained by 1-f where f was the frequency of the premise.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal1-nal5-conversion-contraposition-negation
          ;; Conversion
          ; If S can stand for P P can to a certain low degree also represent the class S
          ; If after S usually P happens then it might be a good guess that usually before P happens S happens.
          #R[(P --&gt; S) (S --&gt; P) |- (P --&gt; S) :post (:t/conversion :p/belief) :pre (:question?)]
          #R[(P ==&gt; S) (S ==&gt; P) |- (P ==&gt; S) :post (:t/conversion :p/belief) :pre (:question?)]
          #R[(P =|&gt; S) (S =|&gt; P) |- (P =|&gt; S) :post (:t/conversion :p/belief) :pre (:question?)]
          #R[(P =\&gt; S) (S =/&gt; P) |- (P =\&gt; S) :post (:t/conversion :p/belief) :pre (:question?)]
          #R[(P =/&gt; S) (S =\&gt; P) |- (P =/&gt; S) :post (:t/conversion :p/belief) :pre (:question?)]
          ;; Contraposition
          ; &quot;If not smoking lets you be healthy being not healthy may be the result of smoking&quot;
          #R[(--S ==&gt; P) P |- (--P ==&gt; S) :post (:t/contraposition :allow-backward)]
          #R[(--S ==&gt; P) --S |- (--P ==&gt; S) :post (:t/contraposition :allow-backward)]
          #R[(--S =|&gt; P) P |- (--P =|&gt; S) :post (:t/contraposition :allow-backward)]
          #R[(--S =|&gt; P) --S |- (--P =|&gt; S) :post (:t/contraposition :allow-backward)]
          #R[(--S =/&gt; P) P |- (--P =\&gt; S) :post (:t/contraposition :allow-backward)]
          #R[(--S =/&gt; P) --S |- (--P =\&gt; S) :post (:t/contraposition :allow-backward)]
          #R[(--S =\&gt; P) P |- (--P =/&gt; S) :post (:t/contraposition :allow-backward)]
          #R[(--S =\&gt; P) --S |- (--P =/&gt; S) :post (:t/contraposition :allow-backward)]
          ; A belief b &lt;f c&gt; is equal to --b &lt;1-f c&gt;  which is the negation rule:
          ;;Negation (resolve by letting termlink be the term on its own for derivation)
          #R[(A --&gt; B) A |- --(A --&gt; B) :post (:t/negation :d/negation :allow-backward)]
          #R[(A --&gt; B) B |- --(A --&gt; B) :post (:t/negation :d/negation :allow-backward)]
          #R[--(A --&gt; B) A |- (A --&gt; B) :post (:t/negation :d/negation :allow-backward)]
          #R[--(A --&gt; B) B |- (A --&gt; B) :post (:t/negation :d/negation :allow-backward)]
          #R[(A &lt;-&gt; B) A |- --(A &lt;-&gt; B) :post (:t/negation :d/negation :allow-backward)]
          #R[(A &lt;-&gt; B) B |- --(A &lt;-&gt; B) :post (:t/negation :d/negation :allow-backward)]
          #R[--(A &lt;-&gt; B) A |- (A &lt;-&gt; B) :post (:t/negation :d/negation :allow-backward)]
          #R[--(A &lt;-&gt; B) B |- (A &lt;-&gt; B) :post (:t/negation :d/negation :allow-backward)]
          #R[(A ==&gt; B) A |- --(A ==&gt; B) :post (:t/negation :d/negation :allow-backward :order-for-all-same)]
          #R[(A ==&gt; B) B |- --(A ==&gt; B) :post (:t/negation :d/negation :allow-backward :order-for-all-same)]
          #R[--(A ==&gt; B) A |- (A ==&gt; B) :post (:t/negation :d/negation :allow-backward :order-for-all-same)]
          #R[--(A ==&gt; B) B |- (A ==&gt; B) :post (:t/negation :d/negation :allow-backward :order-for-all-same)]
          #R[(A &lt;=&gt; B) A |- --(A &lt;=&gt; B) :post (:t/negation :d/negation :allow-backward :order-for-all-same)]
          #R[(A &lt;=&gt; B) B |- --(A &lt;=&gt; B) :post (:t/negation :d/negation :allow-backward :order-for-all-same)]
          #R[--(A &lt;=&gt; B) A |- (A &lt;=&gt; B) :post (:t/negation :d/negation :allow-backward :order-for-all-same)]
          #R[--(A &lt;=&gt; B) B |- (A &lt;=&gt; B) :post (:t/negation :d/negation :allow-backward :order-for-all-same)])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=24" style="text-decoration:none">NAL1 NAL2 Inheritance-Related Syllogisms</a></h1><br/>  <!-- target="bible" -->
          <a href="NAL-Specification.pdf#page=24">Deduction</a>, <a href="NAL-Specification.pdf#page=24">Induction</a> and
          <a href="NAL-Specification.pdf#page=24">Abduction</a> can be naturally represented using the Inheritance-Relation.
          The following rules implement Deduction, Induction and Abduction just based on this relation, while additionally rules for the
          Similarity relation are added.
          The main purpose of these rules is to establish Deduction, Induction, Abduction, for the Inheritance-Copula
          and Analogy and Resemblance as a special case of a deduction for the Similarity copula,
          as well as Comparison as a special case of Induction/Abduction also for the Similarity copula.
          This makes it possible for the system to draw strong conclusions as well as to construct weak but reasonable hypothesis just based on Inheritance-based statements.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal1-nal2-inheritance-related-syllogisms
          ;;Inheritance-Related Syllogisms
          ; If A is a special case of B and B is a special case of C so is A a special case of C (strong) the other variations are hypotheses (weak)
          #R[(A --&gt; B) (B --&gt; C) |- (A --&gt; C) :pre ((:!= A C)) :post (:t/deduction :d/strong :allow-backward)]
          #R[(A --&gt; B) (A --&gt; C) |- (C --&gt; B) :pre ((:!= B C)) :post (:t/abduction :d/weak :allow-backward)]
          #R[(A --&gt; C) (B --&gt; C) |- (B --&gt; A) :pre ((:!= A B)) :post (:t/induction :d/weak :allow-backward)]
          #R[(A --&gt; B) (B --&gt; C) |- (C --&gt; A) :pre ((:!= C A)) :post (:t/exemplification :d/weak :allow-backward)]
          ; similarity from inheritance
          ; If S is a special case of P and P is a special case of S then S and P are similar
          #R[(S --&gt; P) (P --&gt; S) |- (S &lt;-&gt; P) :post (:t/intersection :d/strong :allow-backward)]
          ; inheritance from similarty &lt;- TODO check why this one was missing
          #R[(S &lt;-&gt; P) (P --&gt; S) |- (S --&gt; P) :post (:t/reduce-conjunction :d/strong :allow-backward)]
          ; similarity-based syllogism
          ; If P and S are a special case of M then they might be similar (weak)
          ; also if P and S are a general case of M
          #R[(P --&gt; M) (S --&gt; M) |- (S &lt;-&gt; P) :post (:t/comparison :d/weak :allow-backward) :pre ((:!= S P))]
          #R[(M --&gt; P) (M --&gt; S) |- (S &lt;-&gt; P) :post (:t/comparison :d/weak :allow-backward) :pre ((:!= S P))]
          ; If M is a special case of P and S and M are similar then S is also a special case of P (strong)
          #R[(M --&gt; P) (S &lt;-&gt; M) |- (S --&gt; P) :pre ((:!= S P)) :post (:t/analogy :d/strong :allow-backward)]
          #R[(P --&gt; M) (S &lt;-&gt; M) |- (P --&gt; S) :pre ((:!= S P)) :post (:t/analogy :d/strong :allow-backward)]
          #R[(M &lt;-&gt; P) (S &lt;-&gt; M) |- (S &lt;-&gt; P) :pre ((:!= S P)) :post (:t/resemblance :d/strong :allow-backward)])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=40" style="text-decoration:none">NAL3 Intersection, Union, Difference</a></h1><br/>  <!-- target="bible" -->
           These are the NAL3-related <a href="NAL-Specification.pdf#page=35">union, intersection</a> and <a href="NAL-Specification.pdf#page=37">difference</a> rules,
           allowing the system to create new extensional intersections / intensional intersections and differences based on existing terms.
           A union of instances (extensional union) are a special case of the properties they share, so are a special case of the intersection of the shared properties (intensional intersection)
           Also a union of two properties (intensional union), is a general case of all the instances which have both properties (extensional intersection)
           This symmetry holds when reasoning about the extension and intension, which is why the truth-calculations
           are swapped in the extension-related and intension-related versions of the specific rules.
           The rules here are not used for sets, since it would be redundant,
           for sets there are special rules which follow the same philosophy.
           Additionally no-common-subterm is used to hamper evidence to be counted twice.
           Additionally note that ((S &amp; P) &amp; Q) is automatically reduced to (S &amp; P &amp; Q), same for |, due to the associativity of this operator.
           These rules give the system the ability to form differences, intersections and unions of elements of the generalization hierachy.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal3-intersection-union-difference
          ;; inheritance-based composition
          ; If P and S are in the intension/extension of M then union/difference and intersection can be built:
          #R[(P --&gt; M) (S --&gt; M) |- (((S | P) --&gt; M) :post (:t/intersection)
                                      ((S &amp; P) --&gt; M) :post (:t/union)
                                      ((P ~ S) --&gt; M) :post (:t/difference))
             :pre ((:not-set? S) (:not-set? P)(:!= S P) (:no-common-subterm S P))]
          #R[(M --&gt; P) (M --&gt; S) |- ((M --&gt; (P &amp; S)) :post (:t/intersection)
                                      (M --&gt; (P | S)) :post (:t/union)
                                      (M --&gt; (P - S)) :post (:t/difference))
             :pre ((:not-set? S) (:not-set? P)(:!= S P) (:no-common-subterm S P))])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=86" style="text-decoration:none">NAL3 Inheritance-based Decomposition</a></h1><br/>  <!-- target="bible" -->
          This rules are the opposite of what the above rules represent.
          Instead of composing new intersections, this rules are responsible for decomposing them.
          This gives the system the ability to work with differences, intersections and unions of elements of the generalization hierachy.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal3-inheritance-based-decomposition
          ;; inheritance-based decomposition
          ; if (S --&gt; M) is the case and ((| S :list/A) --&gt; M) is not the case then ((| :list/A) --&gt; M) is not the case hence :t/decompose-pnn
          #R[(S --&gt; M) ((| S :list/A) --&gt; M) |- ((| :list/A) --&gt; M) :post (:t/decompose-pnn)]
          #R[(S --&gt; M) ((&amp; S :list/A) --&gt; M) |- ((&amp; :list/A) --&gt; M) :post (:t/decompose-npp)]
          #R[(S --&gt; M) ((S ~ P) --&gt; M) |- (P --&gt; M) :post (:t/decompose-pnp)]
          #R[(S --&gt; M) ((P ~ S) --&gt; M) |- (P --&gt; M) :post (:t/decompose-nnn)]
          #R[(M --&gt; S) (M --&gt; (&amp; S :list/A)) |- (M --&gt; (&amp; :list/A)) :post (:t/decompose-pnn)]
          #R[(M --&gt; S) (M --&gt; (| S :list/A)) |- (M --&gt; (| :list/A)) :post (:t/decompose-npp)]
          #R[(M --&gt; S) (M --&gt; (S - P)) |- (M --&gt; P) :post (:t/decompose-pnp)]
          #R[(M --&gt; S) (M --&gt; (P - S)) |- (M --&gt; P) :post (:t/decompose-nnn)])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=37" style="text-decoration:none">NAL3 Set-related rules</a></h1><br/>  <!-- target="bible" -->
          These are the set-versions of the rules above. Sets form the boundaries of the taxonomic hierachy
          spanned by the inheritance-statements. A property is a thing for which there can be no further generalization,
          as [furry], while an instance is a thing for which there can be no further specialization, for example {tim}.
          Most statements, are somewhere between properties and instances in the generalization hierachy,
          as most things can indeed be meaningfully specialized and generalized.
          So these set statements are mostly only used by sensors and user input. As example one may consider a sensor which gives information on whether
          the first pixel in the retina is bright: &lt;{pixel1} --> [bright]>. %degree%
          So the purpose of these rules is mainly to form compositions of sensor-related properties and instances.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal3-set-related-rules
          ;; Set comprehension:
          #R[(C --&gt; A) (C --&gt; B) |- (C --&gt; R) :post (:t/union) :pre ((:set-ext? A) (:union A B R))]
          #R[(C --&gt; A) (C --&gt; B) |- (C --&gt; R) :post (:t/intersection) :pre ((:set-int? A) (:union A B R))]
          #R[(A --&gt; C) (B --&gt; C) |- (R --&gt; C) :post (:t/intersection) :pre ((:set-ext? A) (:union A B R))]
          #R[(A --&gt; C) (B --&gt; C) |- (R --&gt; C) :post (:t/union) :pre ((:set-int? A) (:union A B R))]
          #R[(C --&gt; A) (C --&gt; B) |- (C --&gt; R) :post (:t/intersection) :pre ((:set-ext? A) (:intersection A B R))]
          #R[(C --&gt; A) (C --&gt; B) |- (C --&gt; R) :post (:t/union) :pre ((:set-int? A) (:intersection A B R))]
          #R[(A --&gt; C) (B --&gt; C) |- (R --&gt; C) :post (:t/union) :pre ((:set-ext? A) (:intersection A B R))]
          #R[(A --&gt; C) (B --&gt; C) |- (R --&gt; C) :post (:t/intersection) :pre ((:set-int? A) (:intersection A B R))]
          #R[(C --&gt; A) (C --&gt; B) |- (C --&gt; R) :post (:t/difference) :pre ((:difference A B R))]
          #R[(A --&gt; C) (B --&gt; C) |- (R --&gt; C) :post (:t/difference) :pre ((:difference A B R))])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=40" style="text-decoration:none">NAL3 structural inference</a></h1><br/>  <!-- target="bible" -->
           These are some additional meaningful structural deduction rule for the NAL3-statements.
           For example if it is known that a cat is a furry animal, it can be derived that a cat is an animal.
           So these rules are for valid deductions based on the premises containing intersections and differences.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal3-structural-inference
          ; NAL3 single premise inference:
          #R[((| :list/A) --&gt; M) M |- (:from/A --&gt; M) :post (:t/structural-deduction)]
          #R[(M --&gt; (&amp; :list/A)) M |- (M --&gt; :from/A) :post (:t/structural-deduction)]
          #R[((B ~ G) --&gt; S) S |- (B --&gt; S) :post (:t/structural-deduction)]
          #R[(R --&gt; (B - S)) R |- (R --&gt; B) :post (:t/structural-deduction)]
          ; Set element takeout:
          #R[(C --&gt; {:list/A}) C |- (C --&gt; {:from/A}) :post (:t/structural-deduction)]
          #R[(C --&gt; [:list/A]) C |- (C --&gt; [:from/A]) :post (:t/structural-deduction)]
          #R[({:list/A} --&gt; C) C |- ({:from/A} --&gt; C) :post (:t/structural-deduction)]
          #R[([:list/A] --&gt; C) C |- ([:from/A] --&gt; C) :post (:t/structural-deduction)])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=41" style="text-decoration:none">NAL4 structural inference</a></h1><br/>  <!-- target="bible" -->
           The purpose of this rules is structural inference on relations.
           This allows the system to see a specific relation from different perspective,
           as demanded to make arguments of relations themselves possibly be the subject or predicate of an Inheritance-statement.
           For example if the cat eats the mouse, the cat is a special case of something which eats a mouse,
           additionally the mouse is a special case of something which is eaten by the cat,
           additionally the the cat and the mouse are in an anonymous relation which itself is a special case of eating.
           Since this are all different representations of the same relation, the rules use Identity as truth value.
           The key purpose of tese inference rules is to allow the system to do arbitrary relational reasoning
           be exposing all aspects about relations to the generalization hierachy.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal4-structural-inference
          ; NAL4 - Transformations between products and images:
          ; Relations and transforming them into different representations so that arguments and the relation it'self can become the subject or predicate
          #R[((* :list/A) --&gt; M) Ai |- (Ai --&gt; (/ M :list/A))
             :pre ((:substitute-from-list Ai _) (:contains? (:list/A) Ai))
             :post (:t/identity :d/identity)]
          #R[(M --&gt; (* :list/A)) Ai |- ((\ M :list/A) --&gt; Ai)
            :pre ((:substitute-from-list Ai _) (:contains? (:list/A) Ai))
            :post (:t/identity :d/identity)]
            #R[(Ai --&gt; (/ M :list/A )) M |- ((* :list/A) --&gt; M)
               :pre ((:substitute-from-list _ Ai))
               :post (:t/identity :d/identity)]
            #R[((\ M :list/A) --&gt; Ai) M |- (M --&gt; (* :list/A))
            :pre ((:substitute-from-list _ Ai))
            :post (:t/identity :d/identity)]
            ; relation introduction rule:
            ;this one cant be allowed due to control reasons: #_#R[(A --&gt; C) (B --&gt; D) |- ((* A B) --&gt; (* C D)) :post (:t/intersection)]
          #R[(A --&gt; C) (A --&gt; D) |- ((* A A) --&gt; (* C D)) :post (:t/intersection)]
          #R[(A --&gt; C) (B --&gt; C) |- ((* A B) --&gt; (* C C)) :post (:t/intersection)]
          #R[({A} --&gt; C) (A --&gt; D) |- ((* {A} A) --&gt; (* C D)) :post (:t/intersection)]
          #R[(A --&gt; C) ({A} --&gt; D) |- ((* A {A}) --&gt; (* C D)) :post (:t/intersection)]
          #R[(A --&gt; [C]) (B --&gt; C) |- ((* A B) --&gt; (* [C] C)) :post (:t/intersection)]
          #R[(A --&gt; C) (B --&gt; [C]) |- ((* A B) --&gt; (* C [C])) :post (:t/intersection)])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=49" style="text-decoration:none">NAL5 implication based syllogisms</a></h1><br/>  <!-- target="bible" -->
            While Inheritance represents a relation in meaning, Implication represents a relation in truth.
            The meaning of ==> is very natural and roughly corresponds to the implication in classical logic.
            Syllogistic inference for ==> is analogous to how it is in case of -->.
            Also here a two-sided version of the ==> relation, namely &lt;=> is considered, this one is called Equivalence.
            Note that there are temporal variants of these copulas, temporally
            consequent =/> </>, as well as the temporal concurrent copulas =|> &lt;|>.
            For ==> there is an additional =&#92;> relation for "before", allowing the system
            to for example draw deductive conclusion also into the past if the evidence supports them.
            Note that all inference rules with :order-for-all-same also work for this temporal variants,
            even if the inference rule itself only speaks about ==>.
            The key purpose of these rules is to establish deduction, induction, abduction and exemplification for statements using ==> copulas.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal5-implication-based-syllogisms
          ; implication-based syllogism
          #R[(M ==&gt; P) (S ==&gt; M) |- (S ==&gt; P) :post (:t/deduction :order-for-all-same :allow-backward) :pre ((:!= S P))]
          #R[(P ==&gt; M) (S ==&gt; M) |- (S ==&gt; P) :post (:t/induction :allow-backward) :pre ((:!= S P))]
          #R[(P =|&gt; M) (S =|&gt; M) |- (S =|&gt; P) :post (:t/induction :allow-backward) :pre ((:!= S P))]
          #R[(P =/&gt; M) (S =/&gt; M) |- (S =|&gt; P) :post (:t/induction :allow-backward) :pre ((:!= S P))]
          #R[(P =\&gt; M) (S =\&gt; M) |- (S =|&gt; P) :post (:t/induction :allow-backward) :pre ((:!= S P))]
          #R[(M ==&gt; P) (M ==&gt; S) |- (S ==&gt; P) :post (:t/abduction :allow-backward) :pre ((:!= S P))]
          #R[(M =/&gt; P) (M =/&gt; S) |- (S =|&gt; P) :post (:t/abduction :allow-backward) :pre ((:!= S P))]
          #R[(M =|&gt; P) (M =|&gt; S) |- (S =|&gt; P) :post (:t/abduction :allow-backward) :pre ((:!= S P))]
          #R[(M =\&gt; P) (M =\&gt; S) |- (S =|&gt; P) :post (:t/abduction :allow-backward) :pre ((:!= S P))]
          #R[(P ==&gt; M) (M ==&gt; S) |- (S ==&gt; P) :post (:t/exemplification :allow-backward) :pre ((:!= S P))]
          #R[(P =/&gt; M) (M =/&gt; S) |- (S =\&gt; P) :post (:t/exemplification :allow-backward) :pre ((:!= S P))]
          #R[(P =\&gt; M) (M =\&gt; S) |- (S =/&gt; P) :post (:t/exemplification :allow-backward) :pre ((:!= S P))]
          #R[(P =|&gt; M) (M =|&gt; S) |- (S =|&gt; P) :post (:t/exemplification :allow-backward) :pre ((:!= S P))]
          ; //// implication to equivalence ////////////////////////////////////////////////////////////////////////////////////
          ;//If when S happens, P happens, and before P happens, S has happened, then they are truth-related equivalent
          #R[(S ==&gt; P) (P ==&gt; S) |- (S &lt;=&gt; P) :post (:t/intersection :allow-backward) :pre ((:!= S P))]
          #R[(S =|&gt; P) (P =|&gt; S) |- (S &lt;|&gt; P) :post (:t/intersection :allow-backward) :pre ((:!= S P))]
          #R[(S =/&gt; P) (P =\&gt; S) |- (S &lt;/&gt; P) :post (:t/intersection :allow-backward) :pre ((:!= S P))]
          #R[(S =\&gt; P) (P =/&gt; S) |- (P &lt;/&gt; S) :post (:t/intersection :allow-backward) :pre ((:!= S P))]
          ; equivalence-based syllogism
          ; Same as for inheritance again
          #R[(P ==&gt; M) (S ==&gt; M) |- (S &lt;=&gt; P) :pre ((:!= S P)) :post (:t/comparison :allow-backward)]
          #R[(P =/&gt; M) (S =/&gt; M) |- ((S &lt;|&gt; P) :post (:t/comparison :allow-backward)
                                      (S &lt;/&gt; P) :post (:t/comparison :allow-backward)
                                      (P &lt;/&gt; S) :post (:t/comparison :allow-backward))
             :pre ((:!= S P))]
          #R[(P =|&gt; M) (S =|&gt; M) |- (S &lt;|&gt; P) :pre ((:!= S P)) :post (:t/comparison :allow-backward)]
          #R[(P =\&gt; M) (S =\&gt; M) |- ((S &lt;|&gt; P) :post (:t/comparison :allow-backward)
                                      (S &lt;/&gt; P) :post (:t/comparison :allow-backward)
                                      (P &lt;/&gt; S) :post (:t/comparison :allow-backward))
             :pre ((:!= S P))]
          #R[(M ==&gt; P) (M ==&gt; S) |- (S &lt;=&gt; P) :pre ((:!= S P)) :post (:t/comparison :allow-backward)]
          #R[(M =/&gt; P) (M =/&gt; S) |- ((S &lt;|&gt; P) :post (:t/comparison :allow-backward)
                                      (S &lt;/&gt; P) :post (:t/comparison :allow-backward)
                                      (P &lt;/&gt; S) :post (:t/comparison :allow-backward))
             :pre ((:!= S P))]
          #R[(M =|&gt; P) (M =|&gt; S) |- (S &lt;|&gt; P) :pre ((:!= S P)) :post (:t/comparison :allow-backward)]
          ; Same as for inheritance again
          #R[(M ==&gt; P) (S &lt;=&gt; M) |- (S ==&gt; P) :pre ((:!= S P)) :post (:t/analogy :allow-backward)]
          #R[(M =/&gt; P) (S &lt;/&gt; M) |- (S =/&gt; P) :pre ((:!= S P)) :post (:t/analogy :allow-backward)]
          #R[(M =/&gt; P) (S &lt;|&gt; M) |- (S =/&gt; P) :pre ((:!= S P)) :post (:t/analogy :allow-backward)]
          #R[(M =|&gt; P) (S &lt;|&gt; M) |- (S =|&gt; P) :pre ((:!= S P)) :post (:t/analogy :allow-backward)]
          #R[(M =\&gt; P) (M &lt;/&gt; S) |- (S =\&gt; P) :pre ((:!= S P)) :post (:t/analogy :allow-backward)]
          #R[(M =\&gt; P) (S &lt;|&gt; M) |- (S =\&gt; P) :pre ((:!= S P)) :post (:t/analogy :allow-backward)]
          #R[(P ==&gt; M) (S &lt;=&gt; M) |- (P ==&gt; S) :pre ((:!= S P)) :post (:t/analogy :allow-backward)]
          #R[(P =/&gt; M) (S &lt;|&gt; M) |- (P =/&gt; S) :pre ((:!= S P)) :post (:t/analogy :allow-backward)]
          #R[(P =|&gt; M) (S &lt;|&gt; M) |- (P =|&gt; S) :pre ((:!= S P)) :post (:t/analogy :allow-backward)]
          #R[(P =\&gt; M) (S &lt;/&gt; M) |- (P =\&gt; S) :pre ((:!= S P)) :post (:t/analogy :allow-backward)]
          #R[(P =\&gt; M) (S &lt;|&gt; M) |- (P =\&gt; S) :pre ((:!= S P)) :post (:t/analogy :allow-backward)]
          #R[(M &lt;=&gt; P) (S &lt;=&gt; M) |- (S &lt;=&gt; P) :pre ((:!= S P)) :post (:t/resemblance :order-for-all-same :allow-backward)]
          #R[(M &lt;/&gt; P) (S &lt;|&gt; M) |- (S &lt;/&gt; P) :pre ((:!= S P)) :post (:t/resemblance :allow-backward)]
          #R[(M &lt;|&gt; P) (S &lt;/&gt; M) |- (S &lt;/&gt; P) :pre ((:!= S P)) :post (:t/resemblance :allow-backward)])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=50" style="text-decoration:none">NAL5 implication based composition</a></h1><br/>  <!-- target="bible" -->
          Similar as in classical logics, more complicated statements, involving conjunctions and disjunctions can be composed,
          this rules are responsible for this. Note that for the conjunction, &amp;&amp;, there is again a temporal
          variant &amp;| for concurrent conjunction, and &amp;/ for sequential conjunction.
          Note that all conjunction variants are associative, but only &amp;| and &amp;&amp; are commutative exactly as their semantics suggest.
          The key purpose of these rules is to make it possible for the system to identify conditions or preconditions for certain statements.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal5-implication-based-composition
          ; implication-based composition
          ; Same as for inheritance again
          #R[(P ==&gt; M) (S ==&gt; M) |- (((P || S) ==&gt; M) :post (:t/intersection)
                                      ((P &amp;&amp; S) ==&gt; M) :post (:t/union))
             :pre ((:!= S P))]
          #R[(P =|&gt; M) (S =|&gt; M) |- (((P || S) =|&gt; M) :post (:t/intersection)
                                      ((P &amp;| S) =|&gt; M) :post (:t/union))
             :pre ((:!= S P))]
          #R[(P =/&gt; M) (S =/&gt; M) |- (((P || S) =/&gt; M) :post (:t/intersection)
                                      ((P &amp;| S) =/&gt; M) :post (:t/union))
             :pre ((:!= S P)) ]
          #R[(P =\&gt; M) (S =\&gt; M) |- (((P || S) =\&gt; M) :post (:t/intersection)
                                      ((P &amp;| S) =\&gt; M) :post (:t/union))
             :pre ((:!= S P))]
          #R[(M ==&gt; P) (M ==&gt; S) |- ((M ==&gt; (P &amp;&amp; S)) :post (:t/intersection)
                                      (M ==&gt; (P || S)) :post (:t/union))
             :pre ((:!= S P))]
          #R[(M =/&gt; P) (M =/&gt; S) |- ((M =/&gt; (P &amp;| S)) :post (:t/intersection)
                                      (M =/&gt; (P || S)) :post (:t/union))
             :pre ((:!= S P))]
          #R[(M =|&gt; P) (M =|&gt; S) |- ((M =|&gt; (P &amp;| S)) :post (:t/intersection)
                                      (M =|&gt; (P || S)) :post (:t/union))
             :pre ((:!= S P))]
          #R[(M =\&gt; P) (M =\&gt; S) |- ((M =\&gt; (P &amp;| S)) :post (:t/intersection)
                                      (M =\&gt; (P || S)) :post (:t/union))
             :pre ((:!= S P))]
          #R[(D =/&gt; R) (D =\&gt; K) |- ((K =/&gt; R) :post (:t/abduction)
                                      (R =\&gt; K) :post (:t/induction)
                                      (K &lt;/&gt; R) :post (:t/comparison))
             :pre ((:!= R K))])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=49" style="text-decoration:none">NAL5 implication based decomposition and procedural inference</a></h1><br/>  <!-- target="bible" -->
         Analogical to the previous decomposition rules, decomposition rules for the ==> makes it possible for the system to decompose what was composed by the previous rules,
         they key purpose of these rules is to make it possible for the system to derive the consequences of a conditional statement when the condition is fullfilled,
         as well as finding a possible explaination for the truth of the postcondition.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal5-nal8-implication-based-decomposition
          ; implication-based decomposition
          ; Same as for inheritance again
          #R[(S ==&gt; M) ((|| S :list/A) ==&gt; M) |- ((|| :list/A) ==&gt; M) :post (:t/decompose-pnn :order-for-all-same)]
          #R[(S ==&gt; M) ((&amp;&amp; S :list/A) ==&gt; M) |- ((&amp;&amp; :list/A) ==&gt; M) :post (:t/decompose-npp :order-for-all-same :seq-interval-from-premises)]
          #R[(M ==&gt; S) (M ==&gt; (&amp;&amp; S :list/A)) |- (M ==&gt; (&amp;&amp; :list/A)) :post (:t/decompose-pnn :order-for-all-same :seq-interval-from-premises)]
          #R[(M ==&gt; S) (M ==&gt; (|| S :list/A)) |- (M ==&gt; (|| :list/A)) :post (:t/decompose-npp :order-for-all-same)]
          ; conditional syllogism
          ; If after M P usually happens and M happens it means P is expected to happen
          #R[M (M ==&gt; P) |- P :post (:t/deduction :d/induction :order-for-all-same) :pre ((:shift-occurrence-forward ==&gt;))]
          #R[M (P ==&gt; M) |- P :post (:t/abduction :d/deduction :order-for-all-same) :pre ((:shift-occurrence-backward ==&gt;))]
          #R[M (S &lt;=&gt; M) |- S :post (:t/analogy :d/strong :order-for-all-same) :pre ((:shift-occurrence-backward &lt;=&gt;))]
          #R[M (M &lt;=&gt; S) |- S :post (:t/analogy :d/strong :order-for-all-same) :pre ((:shift-occurrence-forward ==&gt;))]
          ; conjunction decompose
          #R[(&amp;&amp; S :list/A) S |- S :post (:t/structural-deduction :d/structural-strong)]
          #R[(&amp;/ S :list/A) S |- S :post (:t/structural-deduction :d/structural-strong)]
          #R[(&amp;| S :list/A) S |- S :post (:t/structural-deduction :d/structural-strong)]
          #R[(&amp;&amp; B :list/A) B |- (&amp;&amp; :list/A) :pre (:goal?) :post (:t/deduction :d/strong :order-for-all-same :seq-interval-from-premises)]
          ; propositional decomposition
          ; If S is the case and (&amp;&amp; S :list/A) is not the case it can't be that (&amp;&amp; :list/A) is the case
          #R[S (&amp;/ S :list/A) |- (&amp;/ :list/A) :post (:t/decompose-pnn :seq-interval-from-premises)]
          #R[S (&amp;| S :list/A) |- (&amp;| :list/A) :post (:t/decompose-pnn)]
          #R[S (&amp;&amp; S :list/A) |- (&amp;&amp; :list/A) :post (:t/decompose-pnn)]
          #R[S (|| S :list/A) |- (|| :list/A) :post (:t/decompose-npp)]
          ; Additional for negation: https://groups.google.com/forum/#!topic/open-nars/g-7r0jjq2Vc
          #R[S (&amp;/ (-- S) :list/A) |- (&amp;/ :list/A) :post (:t/decompose-nnn :seq-interval-from-premises)]
          #R[S (&amp;| (-- S) :list/A) |- (&amp;| :list/A) :post (:t/decompose-nnn)]
          #R[S (&amp;&amp; (-- S) :list/A) |- (&amp;&amp; :list/A) :post (:t/decompose-nnn)]
          #R[S (|| (-- S) :list/A) |- (|| :list/A) :post (:t/decompose-ppp)])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=49" style="text-decoration:none">NAL5 implication based decomposition</a></h1><br/>  <!-- target="bible" -->
          Additionally, there are some rules which allow syllogism-style inference directly happen on compounds with conjunctions,
          whether this rules are really necessary, I am not convinced, but they are at least valid.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal5-multi-conditional-syllogism
          ; multi-conditional syllogism
          ; Inference about the pre/postconditions
          #R[Y ((&amp;&amp; X :list/A) &lt;=&gt; B) |- ((&amp;&amp; :list/A) &lt;=&gt; B) :pre ((:substitute-if-unifies &quot;$&quot; Y X)) :post (:t/deduction :order-for-all-same :seq-interval-from-premises)]
          #R[Y ((&amp;&amp; X :list/A) ==&gt; B) |- ((&amp;&amp; :list/A) ==&gt; B) :pre ((:substitute-if-unifies &quot;$&quot; Y X)) :post (:t/deduction :order-for-all-same :seq-interval-from-premises)]
          #R[((&amp;&amp; M :list/A) ==&gt; C) ((&amp;&amp; :list/B) ==&gt; C) |- M :pre ((:substitute-if-unifies &quot;$&quot; (&amp;&amp; :list/B) (&amp;&amp; :list/A))) :post (:t/abduction :order-for-all-same)]
          ;degenerate case of this rule:
          #R[((&amp;&amp; M U) ==&gt; C) (W ==&gt; C) |- M :pre ((:substitute-if-unifies &quot;$&quot; W U)) :post (:t/abduction :order-for-all-same)]
          ; Can be derived by NAL7 rules so this won't be necessary there (:order-for-all-same left out here)
          ; the first rule does not have :order-for-all-same because it would be invalid see: https://groups.google.com/forum/#!topic/open-nars/r5UJo64Qhrk #R[((&amp;&amp; :list/A) ==&gt; C) M |- ((&amp;&amp; M :list/A) ==&gt; C) :pre ((:not-implication-or-equivalence M)) :post (:t/induction)]
          #R[((&amp;&amp; :list/A) ==&gt; C) M |- ((&amp;&amp; M :list/A) ==&gt; C) :pre ((:not-implication-or-equivalence M)) :post (:t/induction)]
          ;degenerate case of this rule:
          #R[(A ==&gt; C) M |- ((&amp;&amp; M A) ==&gt; C) :pre ((:not-implication-or-equivalence M)) :post (:t/induction)]
          #R[(A &lt;=&gt; M) ((&amp;&amp; M :list/A) ==&gt; C) |- ((&amp;&amp; A :list/A) ==&gt; C) :post (:t/analogy :order-for-all-same :seq-interval-from-premises)]
          #R[(A ==&gt; M) ((&amp;&amp; M :list/A) ==&gt; C) |- ((&amp;&amp; A :list/A) ==&gt; C) :post (:t/deduction :order-for-all-same :seq-interval-from-premises)]
          #R[((&amp;&amp; M :list/A) ==&gt; C) ((&amp;&amp; A :list/A) ==&gt; C) |- (A ==&gt; M) :post (:t/induction :order-for-all-same)]
          #R[(A ==&gt; M) ((&amp;&amp; A :list/A) ==&gt; C) |- ((&amp;&amp; M :list/A) ==&gt; C) :post (:t/abduction :order-for-all-same :seq-interval-from-premises)]
          ; precondition combiner inference rule (variable_unification6):
          #R[((&amp;&amp; C :list/A) ==&gt; Z) ((&amp;&amp; C :list/B) ==&gt; Z) |- (((&amp;&amp; :list/A) ==&gt; (&amp;&amp; :list/B)) :post (:t/induction)
                                                                ((&amp;&amp; :list/B) ==&gt; (&amp;&amp; :list/A)) :post (:t/induction)
                                                                ((&amp;&amp; :list/B) &lt;=&gt; (&amp;&amp; :list/A)) :post (:t/comparison))]
          #R[(Z ==&gt; (&amp;&amp; C :list/A)) (Z ==&gt; (&amp;&amp; C :list/B)) |- (((&amp;&amp; :list/A) ==&gt; (&amp;&amp; :list/B)) :post (:t/abduction)
                                                                ((&amp;&amp; :list/B) ==&gt; (&amp;&amp; :list/A)) :post (:t/abduction)
                                                                ((&amp;&amp; :list/B) &lt;=&gt; (&amp;&amp; :list/A)) :post (:t/comparison))])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=57" style="text-decoration:none">NAL6 Variable Introduction</a></h1><br/>  <!-- target="bible" -->
          The system has the ability to introduce variabes,
          similar as in FOPL where there is a all-quantor and an exists-quantor,
          where here independent-variables correspond to the all-quantor roughly and are written like $X,
          while dependent-variables correspond to the exists-quantor and are written like #X
          Note that there are also temporal variants here,
          allowing the system to introduce variables while not loosing the temporal information between the statements.
          Whether the temporal variants are really needed, is questionable.
          The purpose of variable introduction itself is mainly to make it possible for the system to talk
          abstractly but still precisely about things like the statement "for every lock there exists a key which opens it" demands.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal6-variable-introduction
          ; variable introduction
          ; Introduce variables by common subject or predicate
          #R[(S --&gt; M) (P --&gt; M) |- (((P --&gt; $X) ==&gt; (S --&gt; $X)) :post (:t/abduction)
                                      ((S --&gt; $X) ==&gt; (P --&gt; $X)) :post (:t/induction)
                                      ((P --&gt; $X) &lt;=&gt; (S --&gt; $X)) :post (:t/comparison)
                                      (&amp;&amp; (S --&gt; #Y) (P --&gt; #Y)) :post (:t/intersection))
                                          :pre (:belief? (:!= S P))]
          #R[(S --&gt; M) (P --&gt; M) |- (((&amp;/ (P --&gt; $X) I) =/&gt; (S --&gt; $X)) :post (:t/induction :linkage-temporal :measure-time)
                                      ((S --&gt; $X) =\&gt; (&amp;/ (P --&gt; $X) I)) :post (:t/abduction :linkage-temporal :measure-time)
                                      ((&amp;/ (P --&gt; $X) I) &lt;/&gt; (S --&gt; $X)) :post (:t/comparison :linkage-temporal :measure-time)
                                      (&amp;/ (P --&gt; #Y) I (S --&gt; #Y)) :post (:t/intersection :linkage-temporal :measure-time))
                                        :pre (:belief? (:!= S P) (:measure-time I))]
          #R[(P --&gt; M) (S --&gt; M) |- (((&amp;/ (P --&gt; $X) I) =/&gt; (S --&gt; $X)) :post (:t/induction :linkage-temporal :measure-time)
                                      ((S --&gt; $X) =\&gt; (&amp;/ (P --&gt; $X) I)) :post (:t/abduction :linkage-temporal :measure-time)
                                      ((&amp;/ (P --&gt; $X) I) &lt;/&gt; (S --&gt; $X)) :post (:t/comparison :linkage-temporal :measure-time)
                                      (&amp;/ (P --&gt; #Y) I (S --&gt; #Y)) :post (:t/intersection :linkage-temporal :measure-time))
                                        :pre (:belief? (:!= S P) (:measure-time-backward I))]
          #R[(S --&gt; M) (P --&gt; M) |- (((P --&gt; $X) =|&gt; (S --&gt; $X)) :post (:t/abduction :linkage-temporal)
                                      ((S --&gt; $X) =|&gt; (P --&gt; $X)) :post (:t/induction :linkage-temporal)
                                      ((P --&gt; $X) =|&gt; (S --&gt; $X)) :post (:t/induction :linkage-temporal)
                                      ((P --&gt; $X) &lt;|&gt; (S --&gt; $X)) :post (:t/comparison :linkage-temporal)
                                      (&amp;| (P --&gt; #Y) (S --&gt; #Y)) :post (:t/intersection :linkage-temporal))
                                          :pre (:belief? (:!= S P) (:concurrent Task Belief))]
          #R[(M --&gt; S) (M --&gt; P) |- ((($X --&gt; S) ==&gt; ($X --&gt; P)) :post (:t/induction)
                                      (($X --&gt; P) ==&gt; ($X --&gt; S)) :post (:t/abduction)
                                      (($X --&gt; S) &lt;=&gt; ($X --&gt; P)) :post (:t/comparison)
                                      (&amp;&amp; (#Y --&gt; S) (#Y --&gt; P)) :post (:t/intersection))
             :pre (:belief? (:!= S P)) ]
          #R[(M --&gt; S) (M --&gt; P) |- (((&amp;/ ($X --&gt; P) I) =/&gt; ($X --&gt; S))  :post (:t/induction :linkage-temporal :measure-time)
                                      (($X --&gt; S) =\&gt; (&amp;/ ($X --&gt; P) I)) :post (:t/abduction :linkage-temporal :measure-time)
                                      ((&amp;/ ($X --&gt; P) I) &lt;/&gt; ($X --&gt; S)) :post (:t/comparison :linkage-temporal :measure-time)
                                      (&amp;/ (#Y --&gt; P) I (#Y --&gt; S)) :post (:t/intersection :linkage-temporal :measure-time))
             :pre (:belief? (:!= S P) (:measure-time I))]
          #R[(M --&gt; P) (M --&gt; S) |- (((&amp;/ ($X --&gt; P) I) =/&gt; ($X --&gt; S))  :post (:t/induction :linkage-temporal :measure-time)
                                      (($X --&gt; S) =\&gt; (&amp;/ ($X --&gt; P) I)) :post (:t/abduction :linkage-temporal :measure-time)
                                      ((&amp;/ ($X --&gt; P) I) &lt;/&gt; ($X --&gt; S)) :post (:t/comparison :linkage-temporal :measure-time)
                                      (&amp;/ (#Y --&gt; P) I (#Y --&gt; S)) :post (:t/intersection :linkage-temporal :measure-time))
             :pre (:belief? (:!= S P) (:measure-time-backward I))]
          #R[(M --&gt; S) (M --&gt; P) |- ((($X --&gt; S) =|&gt; ($X --&gt; P)) :post (:t/induction :linkage-temporal)
                                      (($X --&gt; P) =|&gt; ($X --&gt; S)) :post (:t/abduction :linkage-temporal)
                                      (($X --&gt; S) =|&gt; ($X --&gt; P)) :post (:t/abduction :linkage-temporal)
                                      (($X --&gt; S) &lt;|&gt; ($X --&gt; P)) :post (:t/comparison :linkage-temporal)
                                      (&amp;| (#Y --&gt; S) (#Y --&gt; P)) :post (:t/intersection :linkage-temporal))
             :pre (:belief? (:!= S P) (:concurrent (M --&gt; P) (M --&gt; S)))])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=57" style="text-decoration:none">NAL6 Variable Syllogisms</a></h1><br/>  <!-- target="bible" -->
          Additionally, these rules are valid due to the semantics of the dependent variables.
          Whether these rules are really needed is however questionable.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal6-variable-syllogisms
          ; conditional abduction by dependent variable
          #R[((A --&gt; R) ==&gt; Z) ((&amp;&amp; (#Y --&gt; B) (#Y --&gt; R) :list/A) ==&gt; Z) |- (A --&gt; B) :post (:t/abduction)]
          #R[((A --&gt; R) ==&gt; Z) ((&amp;&amp; (#Y --&gt; B) (#Y --&gt; R)) ==&gt; Z) |- (A --&gt; B) :post (:t/abduction)]
          ; conditional deduction &quot;An inverse inference has been implemented as a form of deduction&quot; https://code.google.com/p/open-nars/issues/detail?id=40&amp;can=1
          #R[(U --&gt; L) ((&amp;&amp; (#X --&gt; L) (#X --&gt; R)) ==&gt; Z) |- ((U --&gt; R) ==&gt; Z) :post (:t/deduction)]
          #R[(U --&gt; L) ((&amp;&amp; (#X --&gt; L) (#X --&gt; R) :list/A) ==&gt; Z) |- ((&amp;&amp; (U --&gt; R) :list/A) ==&gt; Z) :pre ((:substitute #X U)) :post (:t/deduction)])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=57" style="text-decoration:none">NAL6 Multiple Variable Introduction</a></h1><br/>  <!-- target="bible" -->
          In order to introduce additional variables and after one was already introduced,
          and in order to handle multiples these, these rules exist,
          allowing the system to create more complicated abstractions and to work with them.
          The purpose of these rules is the same as for variable introduction, while extending the principle to an arbitrary amount of variables.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal6-multiple-variable-introduction
          ; 2nd variable introduction
          #R[(A ==&gt; (M --&gt; P)) (M --&gt; S) |- (((&amp;&amp; A ($X --&gt; S)) ==&gt; ($X --&gt; P)) :post (:t/induction)
                                              (&amp;&amp; (A ==&gt; (#Y --&gt; P)) (#Y --&gt; S)) :post (:t/intersection))
             :pre ((:!= A (M --&gt; S)))]
          #R[(&amp;&amp; (M --&gt; P) :list/A) (M --&gt; S) |- ((($Y --&gt; S) ==&gt; (&amp;&amp; ($Y --&gt; P) :list/A)) :post (:t/induction)
                                                   (&amp;&amp; (#Y --&gt; S) (#Y --&gt; P) :list/A) :post (:t/intersection))
             :pre ((:!= S P))]
          #R[(A ==&gt; (P --&gt; M)) (S --&gt; M) |- (((&amp;&amp; A (P --&gt; $X)) ==&gt; (S --&gt; $X)) :post (:t/abduction)
                                              (&amp;&amp; (A ==&gt; (P --&gt; #Y)) (S --&gt; #Y)) :post (:t/intersection))]
          #R[(&amp;&amp; (P --&gt; M) :list/A) (S --&gt; M) |- (((S --&gt; $Y) ==&gt; (&amp;&amp; (P --&gt; $Y) :list/A))  :post (:t/abduction)
                                                   (&amp;&amp;  (S --&gt; #Y) (P --&gt; #Y) :list/A) :post (:t/intersection))
                                                        :pre ((:!= S P))]
          #R[(A --&gt; L) ((A --&gt; S) ==&gt; R) |- ((&amp;&amp; (#X --&gt; L) (#X --&gt; S)) ==&gt; R) :post (:t/induction)]
          #R[(A --&gt; L) ((&amp;&amp; (A --&gt; S) :list/A) ==&gt; R) |- ((&amp;&amp; (#X --&gt; L) (#X --&gt; S) :list/A) ==&gt; R) :pre ((:substitute A #X)) :post (:t/induction)])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=57" style="text-decoration:none">NAL6 Variable Elimination</a></h1><br/>  <!-- target="bible" -->
          Additionally, the system has to be able to eliminate variables by filling in the pattern of the second premise,
          so to specialize a statement when a premise fits in its scheme, this holds for independent as well as dependent variables.
          The purpose of this is to specialize general statements containing variables to specific cases.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal6-variable-elimination
          ; dependent variable elimination
          ; Decomposition with elimination of a variable
          #R[B (&amp;&amp; A :list/A) |- (&amp;&amp; :list/A) :pre (:belief? (:substitute-if-unifies &quot;#&quot; B A)) :post (:t/anonymous-analogy :d/strong :order-for-all-same :seq-interval-from-premises)]
          ;and for the goal-task belief combination:
          #R[(&amp;&amp; A :list/A) B |- (&amp;&amp; :list/A) :pre (:goal? (:substitute-if-unifies &quot;#&quot; B A)) :post (:t/deduction :d/strong :order-for-all-same :seq-interval-from-premises)]
          ; independent variable elimination
          #R[B (A ==&gt; C) |- C :post (:t/deduction :d/induction :order-for-all-same) :pre ((:substitute-if-unifies &quot;$&quot; B A) (:shift-occurrence-forward ==&gt;))]
          #R[B (C ==&gt; A) |- C :post (:t/abduction :d/deduction :order-for-all-same) :pre ((:substitute-if-unifies &quot;$&quot; B A) (:shift-occurrence-backward ==&gt;))]
          #R[B (A &lt;=&gt; C) |- C :post (:t/analogy :d/deduction :order-for-all-same) :pre ((:substitute-if-unifies &quot;$&quot; B A) (:shift-occurrence-forward &lt;=&gt;))]
          #R[B (C &lt;=&gt; A) |- C :post (:t/analogy :d/deduction :order-for-all-same) :pre ((:substitute-if-unifies &quot;$&quot; B A) (:shift-occurrence-backward &lt;=&gt;))])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=57" style="text-decoration:none">NAL6 Second Level Variable Handling</a></h1><br/>  <!-- target="bible" -->
          There were some meaningful cases where variables had to be handled by specific rules at a deeper level,
          this is what these rules are about. I am still not convinced whether these rules are really needed though.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal6-second-layer-variable-handling
          ; second level variable handling rules
          ; second level variable elimination (termlink level2 growth needed in order for these rules to work)
          #R[(A --&gt; K) (&amp;&amp; (#X --&gt; L) (($Y --&gt; K) ==&gt; (&amp;&amp; :list/A))) |- (&amp;&amp; (#X --&gt; L) :list/A) :pre ((:substitute $Y A)) :post (:t/deduction)]
          ;degenerate case of this rule:
          #R[(A --&gt; K) (&amp;&amp; (#X --&gt; L) (($Y --&gt; K) ==&gt; A)) |- (&amp;&amp; (#X --&gt; L) A) :pre ((:substitute $Y A)) :post (:t/deduction)]
          #R[(A --&gt; K) (($X --&gt; L) ==&gt; (&amp;&amp; (#Y --&gt; K) :list/A)) |- (($X --&gt; L) ==&gt; (&amp;&amp; :list/A)) :pre ((:substitute #Y A)) :post (:t/anonymous-analogy)])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=61" style="text-decoration:none">NAL7 Temporal Inference</a></h1><br/>  <!-- target="bible" -->
          Altough all above rules also work for temporal statements, there are rules which are only for reasoning about time,
          these are them. The most important one of these is temporal induction:
          Temporal induction, a NAL7 principle, allows the system to temporally relate events.
          the <b> ==&gt; &lt;=&gt; </b> truth-related copulas are extended to capture whether two events happen after
          each other, <b> a =/> b  </b>, or concurrently <b> a =|&gt; </b> These operators are all transitive, also
          \( \forall a,b,c \) events with truth values \( T1, T2 \in [0, 1] \times [0, 1]: \)
          <b> a =/> b </b> \( \wedge \) <b> b =|> c </b> \( \implies \) <b> a =|> c </b> with truth-value
          <b> induction( T1 , T2) </b> holds, consistent with the semantics of the copulas. Additionally intervals are
          used to measure the temporal occurrence time difference between the events. In order to support this,
          predicate <b> measure_time(I)</b> is introduced which is true if and only if the the time difference between
          both event premises is <b> I </b>. In the language, the time difference is encoded in the sequence, for
          example <b> ((&amp;/,a,/10) =/> b) </b> encodes that <b> b </b> happens <b> 10  </b>  steps after <b> a </b>.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules nal7-temporal-inference
          &quot;&lt;h1&gt;&lt;a href=\&quot;NAL-Specification.pdf#page=61\&quot; style=\&quot;text-decoration:none\&quot;&gt;NAL7 Temporal Inference&lt;/a&gt;&lt;/h1&gt;&lt;br/&gt;  &lt;!-- target=\&quot;bible\&quot; --&gt;
          Altough all above rules also work for temporal statements, there are rules which are only for reasoning about time,
          these are them. The most important one of these is temporal induction:
          Temporal induction, a NAL7 principle, allows the system to temporally relate events.
          the &lt;b&gt; ==&amp;gt; &amp;lt;=&amp;gt; &lt;/b&gt; truth-related copulas are extended to capture whether two events happen after
          each other, &lt;b&gt; a =/&gt; b  &lt;/b&gt;, or concurrently &lt;b&gt; a =|&amp;gt; &lt;/b&gt; These operators are all transitive, also
          \\\\( \\forall a,b,c \\\\) events with truth values \\\\( T1, T2 \\in \\[0, 1\\] \\times \\[0, 1\\]: \\\\)
          &lt;b&gt; a =/&gt; b &lt;/b&gt; \\\\( \\wedge \\\\) &lt;b&gt; b =|&gt; c &lt;/b&gt; \\\\( \\implies \\\\) &lt;b&gt; a =|&gt; c &lt;/b&gt; with truth-value
          &lt;b&gt; induction( T1 , T2) &lt;/b&gt; holds, consistent with the semantics of the copulas. Additionally intervals are
          used to measure the temporal occurrence time difference between the events. In order to support this,
          predicate &lt;b&gt; measure_time(I)&lt;/b&gt; is introduced which is true if and only if the the time difference between
          both event premises is &lt;b&gt; I &lt;/b&gt;. In the language, the time difference is encoded in the sequence, for
          example &lt;b&gt; ((&amp;/,a,/10) =/&gt; b) &lt;/b&gt; encodes that &lt;b&gt; b &lt;/b&gt; happens &lt;b&gt; 10  &lt;/b&gt;  steps after &lt;b&gt; a &lt;/b&gt;.&quot;
          ; Temporal induction:
          ; When P and then S happened according to an observation by induction (weak) it may be that alyways after P usually S happens.
          #R[P S |- (((&amp;/ S I) =/&gt; P) :post (:t/induction :linkage-temporal :measure-time)
                      (P =\&gt; (&amp;/ S I)) :post (:t/abduction :linkage-temporal :measure-time)
                      ((&amp;/ S I) &lt;/&gt; P) :post (:t/comparison :linkage-temporal :measure-time)
                      (&amp;/ S I P) :post (:t/intersection :linkage-temporal :measure-time))
             :pre (:belief? (:measure-time I) (:not-implication-or-equivalence P) (:not-implication-or-equivalence S) (:!= S P))]
          #R[S P |- (((&amp;/ S I) =/&gt; P) :post (:t/induction :linkage-temporal :measure-time)
                      (P =\&gt; (&amp;/ S I)) :post (:t/abduction :linkage-temporal :measure-time)
                      ((&amp;/ S I) &lt;/&gt; P) :post (:t/comparison :linkage-temporal :measure-time)
                      (&amp;/ S I P) :post (:t/intersection :linkage-temporal :measure-time))
             :pre (:belief? (:measure-time-backward I) (:not-implication-or-equivalence P) (:not-implication-or-equivalence S) (:!= S P))]
          #R[P S |- ((S =|&gt; P) :post (:t/induction :linkage-temporal)
                      (P =|&gt; S) :post (:t/induction :linkage-temporal)
                      (S &lt;|&gt; P) :post (:t/comparison :linkage-temporal)
                      (&amp;| S P) :post (:t/intersection :linkage-temporal))
             :pre [:belief? (:concurrent Task Belief) (:not-implication-or-equivalence P) (:not-implication-or-equivalence S) (:!= S P)]])</pre></td></tr><tr><td class="docs"><p><h1><a href="NAL-Specification.pdf#page=57" style="text-decoration:none">Backward Inference rules</a></h1><br/>  <!-- target="bible" -->
          Most backward inference is captured by deriving two additional rules
          per forward rule, where one premise is exchanged with the conclusion,
          with addtional task("?") predicate added. In this section we see backward rules which
          would not be captured by this principle.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules backward-only-inference
          ; here now are the backward inference rules which should really only work on backward inference:
          #R[(A --&gt; S) (B --&gt; S) |- ((A --&gt; B) :post (:p/question)
                                      (B --&gt; A) :post (:p/question)
                                      (A &lt;-&gt; B) :post (:p/question))
             :pre (:question?)])</pre></td></tr><tr><td class="docs"><p><h1>Backward driven forward inference</h1><br/>  <!-- target="bible" -->
          For some rules it is better to only let them succeed if there is a question which explicitly asks for their result.
          However whether this is really needed is questionable for me, but it has benefits in the preliminary form
          our control mechanism currently is in.</p>
</td><td class="codes"><pre class="brush: clojure">(defrules backward-driven-forward-inference
          ; and the backward inference driven forward inference:
          ; NAL2:
          #R[([A] &lt;-&gt; [B]) (A &lt;-&gt; B) |- ([A] &lt;-&gt; [B]) :pre (:question?) :post (:t/belief-identity :p/belief)]
          #R[({A} &lt;-&gt; {B}) (A &lt;-&gt; B) |- ({A} &lt;-&gt; {B}) :pre (:question?) :post (:t/belief-identity :p/belief)]
          #R[([A] --&gt; [B]) (A &lt;-&gt; B) |- ([A] --&gt; [B]) :pre (:question?) :post (:t/belief-identity :p/belief)]
          #R[({A} --&gt; {B}) (A &lt;-&gt; B) |- ({A} --&gt; {B}) :pre (:question?) :post (:t/belief-identity :p/belief)]
          ; NAL3:
          ; composition on both sides of a statement:
          #R[((&amp; B :list/A) --&gt; (&amp; A :list/A)) (B --&gt; A) |- ((&amp; B :list/A) --&gt; (&amp; A :list/A)) :pre (:question?) :post (:t/belief-structural-deduction :p/belief)]
          #R[((| B :list/A) --&gt; (| A :list/A)) (B --&gt; A) |- ((| B :list/A) --&gt; (| A :list/A)) :pre (:question?) :post (:t/belief-structural-deduction :p/belief)]
          #R[((- S A) --&gt; (- S B)) (B --&gt; A) |- ((- S A) --&gt; (- S B)) :pre (:question?) :post (:t/belief-structural-deduction :p/belief)]
          #R[((~ S A) --&gt; (~ S B)) (B --&gt; A) |- ((~ S A) --&gt; (~ S B)) :pre (:question?) :post (:t/belief-structural-deduction :p/belief)]
          ; composition on one side of a statement:
          #R[(W --&gt; (| B :list/A)) (W --&gt; B) |- (W --&gt; (| B :list/A)) :pre (:question?) :post (:t/belief-structural-deduction :p/belief)]
          #R[((&amp; B :list/A) --&gt; W) (B --&gt; W) |- ((&amp; B :list/A) --&gt; W) :pre (:question?) :post (:t/belief-structural-deduction :p/belief)]
          #R[(W --&gt; (- S B)) (W --&gt; B) |- (W --&gt; (- S B)) :pre (:question?) :post (:t/belief-structural-difference :p/belief)]
          #R[((~ S B) --&gt; W) (B --&gt; W) |- ((~ S B) --&gt; W) :pre (:question?) :post (:t/belief-structural-difference :p/belief)]
          ; NAL4:
          ; composition on both sides of a statement:
          #R[((* B P) --&gt; Z) (B --&gt; A) |- ((* B P) --&gt; (* A P)) :pre (:question?) :post (:t/belief-structural-deduction :p/belief)]
          #R[((* P B) --&gt; Z) (B --&gt; A) |- ((* P B) --&gt; (* P A)) :pre (:question?) :post (:t/belief-structural-deduction :p/belief)]
          #R[((* B P) &lt;-&gt; Z) (B &lt;-&gt; A) |- ((* B P) &lt;-&gt; (* A P)) :pre (:question?) :post (:t/belief-structural-deduction :p/belief)]
          #R[((* P B) &lt;-&gt; Z) (B &lt;-&gt; A) |- ((* P B) &lt;-&gt; (* P A)) :pre (:question?) :post (:t/belief-structural-deduction :p/belief)]
          #R[((\ N A _) --&gt; Z) (N --&gt; R) |- ((\ N A _) --&gt; (\ R A _)) :pre (:question?) :post (:t/belief-structural-deduction :p/belief)]
          #R[((/ N _ B) --&gt; Z) (S --&gt; B) |- ((/ N _ B) --&gt; (/ N _ S)) :pre (:question?) :post (:t/belief-structural-deduction :p/belief)]
          ; NAL5:
          #R[--A    A |- --A  :pre (:question?) :post (:t/belief-negation :p/belief)]
          #R[A  --A |-   A  :pre (:question?) :post (:t/belief-negation :p/belief)]
          ; compound composition one premise
          #R[(|| B :list/A) B |- (|| B :list/A) :pre (:question?) :post (:t/belief-structural-deduction :p/belief)])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def rules (compile-rules nal1-nal2-nal3-equivalence-and-implication nal1-nal5-conversion-contraposition-negation nal1-nal2-inheritance-related-syllogisms
                          nal3-intersection-union-difference nal3-inheritance-based-decomposition nal3-set-related-rules nal3-structural-inference
                          nal4-structural-inference nal5-implication-based-syllogisms nal5-implication-based-composition nal5-nal8-implication-based-decomposition
                          nal5-multi-conditional-syllogism nal6-variable-introduction nal6-variable-syllogisms nal6-multiple-variable-introduction
                          nal6-variable-elimination nal6-second-layer-variable-handling nal7-temporal-inference backward-only-inference backward-driven-forward-inference))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn freq [task-type]
  &quot;Check frequency&quot;
  (into {} (map (fn [[k v]] [(str k) (count (:rules v))]) (task-type rules))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn stats [task-type]
  (let [fr (freq task-type)]
    (println &quot;Total&quot; (reduce + (vals fr)))
    (println &quot;Total keys&quot; (count (task-type rules)))
    (println &quot;Freq&quot; (sort (frequencies (vals fr))))
    (println &quot;Min&quot; (reduce min (vals fr)))
    (println &quot;Max&quot; (reduce (fn [[_ v1 :as p] [_ v :as n]]
                             (if (&gt; v1 v) p n)) fr))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.term_utils" name="nal.term_utils"><h1 class="project-name">nal.term_utils</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.term_utils
  (:require [clojure.set :as set]
            [narjure.defaults :refer :all]
            [clojure.core.unify :refer [unify]]))</pre></td></tr><tr><td class="docs"><p>Is the term an interval?</p>
</td><td class="codes"><pre class="brush: clojure">(defn interval?
  [content]
  (and (sequential? content) (= (first content) :interval)))</pre></td></tr><tr><td class="docs"><p>Checks whether st is an operation, namely a term of form &lt;(*,{SELF},arg) --> op_name></p>
</td><td class="codes"><pre class="brush: clojure">(defn operation?
  [st]
  (if (and (coll? st)
           (= (first st) '--&gt;)
           (coll? (second st))
           (= (first (second st)) '*)
           (or (= (second (second st)) ['ext-set 'SELF])
               (= (second (second st)) ['ext-set 'SELF2])))
    (let [op (nth st 2)]
      (and (not (coll? op))
           (clojure.string/starts-with? (name op) &quot;op_&quot;)))
    (clojure.string/starts-with? (str st) &quot;self_op_&quot;)))</pre></td></tr><tr><td class="docs"><p>Checks whether st is the negation of an operation</p>
</td><td class="codes"><pre class="brush: clojure">(defn negation-of-operation?
  [st]
  (and (coll? st)
       (= (first st) '--)
       (operation? (second st))))</pre></td></tr><tr><td class="docs"><p>Checks whether it is a variable symbol</p>
</td><td class="codes"><pre class="brush: clojure">(defn variable?
  [t]
  (and (coll? t) (or (= (first t) 'ind-var)
                     (= (first t) 'dep-var)
                     (= (first t) 'qu-var))))</pre></td></tr><tr><td class="docs"><p>Is the term a compound term?</p>
</td><td class="codes"><pre class="brush: clojure">(defn compound?
  [content]
  (and (sequential? content) (not= (first content) :interval) (not (variable? content))))</pre></td></tr><tr><td class="docs"><p>Calculates the syntactic complexity of a content term,
  for example (| (&amp; a b) c) has complexity 5</p>
</td><td class="codes"><pre class="brush: clojure">(defn syntactic-complexity
  [content]
  (if (compound? content)
    (reduce + (map syntactic-complexity content))
    1))</pre></td></tr><tr><td class="docs"><p>todo -  temp function below should be in nal.clj - Patham9 to resolve</p>
</td><td class="codes"><pre class="brush: clojure">(def logic-ops
  #{'--&gt; '&lt;-&gt; 'instance 'property 'instance-property '==&gt; 'pred-impl '=|&gt; 'retro-impl '&lt;=&gt; '&lt;/&gt; '&lt;|&gt; 'ext-set 'int-set 'ext-inter '| '- 'int-dif '* 'ext-image 'int-image '-- '|| 'conj 'seq-conj '&amp;|})</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn placeholder? [t] (= '_ t))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn is-singular-sequence [st]
  &quot;Checks whether the sequence is of (&amp;/,a) form&quot;
  (and (coll? st)
       (= (count st) 2)
       (= (first st) 'seq-conj)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn reduce-sequence [st]                                  ;TODO move to term utils!!
  &quot;Replaces (&amp;/,a) =&gt; a recursively&quot;
  (if (coll? st)
    (if (is-singular-sequence st)
      (second st)
      (apply vector (for [x st]
                      (reduce-sequence x))))
    (if (is-singular-sequence st)
      (second st)
      st)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn interval-only-sequence [st]                                ;TODO move to term utils!!
  &quot;checks whether st is of form (&amp;/,[:interval n]),
  if yes, return n&quot;
  (when (and (coll? st)
             (= (first st) 'seq-conj)
             (= (count st) 2)
             (coll? (second st))
             (= (first (second st)) :interval))
    (second (second st))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn is-implication [st]                                   ;TODO move to term utils!!
  &quot;checks whether the statement st is an implication&quot;
  (and (coll? st)
       (or (= (first st) 'pred-impl)
           (= (first st) '==&gt;)
           (= (first st) '=|&gt;))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn interval-at [f st]                                    ;TODO move to term utils!!
  &quot;Returns the f=first/last etc. interval of a sequence st&quot;
  (when (and (coll? st)
             (= (first st) 'seq-conj)
             (coll? (f st))
             (= (first (f st)) :interval))
    (second (f st))))</pre></td></tr><tr><td class="docs"><p>Reductions for intervals/sequences</p>
</td><td class="codes"><pre class="brush: clojure">(defn interval-reduction
  [s]                                   ;TODO move to sentence utils?
  ;there are certain equivalence transformations only being valid in ''NAL7i (NAL7+Intervals)
  ;''and which indicate how intervals have to be treated as occurrence time modulators.
  ;These are:
  ;''Forward Interval'':
  ;&lt; (&amp;/, i10) ==&gt; b&gt; = &lt;i10 ==&gt; b&gt; = b. :/10:
  ;(&amp;/,i10,a_1, ..., a_n) = (&amp;/,a_1, ..., a_n). :/10:
  ;''Backward Interval'':
  ;&lt;a ==&gt; (&amp;/, i10)&gt; = &lt;a ==&gt; i10&gt; = a. :\10:
  ;(&amp;/, a_1, ..., a_n, /10) = (&amp;/, a_1, ..., a_n) . :\10:
  ;this term is only derived as a A detachment from A =/&gt; B this is why this treatment is valid.
  ;Also note that these are mandatory reductions, as else if i10 is treated as normal terms,
  ;semantical nonsense could be derived if an interval alone is the subject or predicate of an implication
  ;or an event itself, since strictly speaking an interval itself does not encode an event semantically
  ;but only measures the distance between them!
  (let [ival-reducer
        (fn [st]
          (if (is-implication st)
            (let [subject (second st)
                  predicate (nth st 2)
                  ivalseq-s (interval-only-sequence subject)
                  ivalseq-p (interval-only-sequence predicate)]
              (if ivalseq-s
                [predicate ivalseq-s]                       ;&lt;(&amp;/, i10) ==&gt; b&gt; = &lt;i10 ==&gt; b&gt; = b. :/10:
                (if ivalseq-p
                  [subject (- ivalseq-p)]
                  [(reduce-sequence st) 0])))                                 ;&lt;a ==&gt; (&amp;/, i10)&gt; = &lt;a ==&gt; i10&gt; = a. :\10:
            (if (and (coll? st)
                     (= 'seq-conj (first st)))
              (let [ival-l (interval-at second st)
                    ival-r (interval-at last st)]
                (if ival-l
                  [(reduce-sequence (apply vector (first st) (rest (rest st)))) ival-l] ;(&amp;/,i10,a_1, ..., a_n) = (&amp;/,a_1, ..., a_n). :/10:
                  (if ival-r
                    [(reduce-sequence (apply vector (drop-last st))) (- ival-r)] ;(&amp;/, a_1, ..., a_n, /10) = (&amp;/, a_1, ..., a_n) . :\10:
                    [(reduce-sequence st) 0])))
              [(reduce-sequence st) 0])))]                                       ;TODO (&amp;/ case) !!!!!
    (let [occurence (:occurrence s)
          [st shift] (ival-reducer (:statement s))]
      (assoc (assoc s :statement st) :occurrence
                                     (if (= :eternal occurence)
                                       :eternal
                                       (+ occurence shift))))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn next-interval-point [n]                               ;term-utils
  &quot;for establishing tolerance in temporal distance,
  by rounding to the next power of 2&quot;
  (let [pot-2 (for [i (range 25)]
                (int (Math/pow 2 i)))]
    (first (for [x (filter #(&gt; % n) pot-2)]
             (if (&lt; (Math/abs (- x n))
                    (Math/abs (- (/ x 2) n)))
               x
               (/ x 2))))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn str-is-integer [s]
  (when (not= s )
    (every? #(Character/isDigit %) s)))</pre></td></tr><tr><td class="docs"><p>Change the interval atom to an interval</p>
</td><td class="codes"><pre class="brush: clojure">(defn interval-atom-to-interval
  [t]
  (let [pot-ival (name t)
        num (apply str (rest pot-ival))]
    (if (and (= \i (first pot-ival))
             (str-is-integer num))
      [:interval (next-interval-point (Integer/parseInt num))]
      t)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn parse-intervals [t]
  &quot;all occurrences of i50 in the term are transformed to [:interval 50]&quot;
  (if (coll? t)
    (apply vector
           (for [x t]
             (parse-intervals x)))
    (interval-atom-to-interval t)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn apply-interval-precision [t]
  &quot;all intervals are changed to the next interval precision point
  in this magnitude&quot;
  (if (coll? t)
    (if (= (first t) :interval)
      [:interval (next-interval-point (second t))]
      (apply vector
             (for [x t]
               (apply-interval-precision x))))
    t))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn apply-interval-concept-term-transform [t]
  &quot;all intervals are changed to the next interval precision point
  in this magnitude&quot;
  (if (coll? t)
    (if (= (first t) :interval)
      [:interval &quot;x&quot;]
      (apply vector
             (for [x t]
               (apply-interval-concept-term-transform x))))
    t))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn concept-term-transform [t]
  (let [term (if (and (coll? t)   ;conceptualize (&amp;/,a,i13) as a
                      (= (count t) 3)
                      (= (first t) 'seq-conj)
                      (interval? (last t)))
               (second t)
               t)]
    (apply-interval-concept-term-transform term)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn statement-and-conceptid-equal [statement concept-id]
  &quot;same in respect to intervals&quot;
  (= (concept-term-transform statement)
     concept-id))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn not-statement-and-conceptid-equal [statement concept-id]
  &quot;not same in respect to intervals&quot;
  (not (statement-and-conceptid-equal statement concept-id)))</pre></td></tr><tr><td class="docs"><p>Extract the termlink relevant subterms of the term up to 3 levels as demanded by the NAL rules</p>
</td><td class="codes"><pre class="brush: clojure">(defn termlink-subterms
  ([level content]
   (if (and (&lt; level 3) (compound? content))
     (reduce set/union #{content} (map (partial termlink-subterms (inc level)) content))
     #{content}))
  ([content]
   (remove #(or (logic-ops %) (interval? %) (placeholder? %) (variable? %))
           (map concept-term-transform (termlink-subterms 0 content)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn no-truth-for-questions-and-quests [st]         ;sentence util
  &quot;makes absolutely sure that goals and beliefs have no truth and desire value for now&quot;
  (if (or (= (:task-type st) :quest)
          (= (:task-type st) :question))
    (dissoc st :truth)
    st))</pre></td></tr><tr><td class="docs"><p>get the so far max. used variable number
  to illustrate: (max-var-term '[conj [disj [dep-var 2]] [ind-var 1]]) => 2</p>
</td><td class="codes"><pre class="brush: clojure">(defn max-var-term
  ([st]
   (max-var-term st 0))
  ([st m]
   (if (coll? st)
     (if (and (or (= (first st) 'ind-var)
                  (= (first st) 'dep-var))
              (str-is-integer (str (second st))))
       (read-string (str (second st)))                     ;dangerous? ^^
       (apply max (for [x st]
                    (max-var-term x))))
     m)))</pre></td></tr><tr><td class="docs"><p>inference rules introduce one #X or $X, #Y or $Y variable,
  we use the maximum so far existing variable number and add one,
  in order for new introduced variables to
  have a unique variable name when the old variables
  were of the form $i #k. Should be fine for most purposes for now.</p>
</td><td class="codes"><pre class="brush: clojure">(defn normalize-variables
  ([st]
   (normalize-variables st (inc (max-var-term st))))
  ([st m]
   (if (coll? st)
     (if (or (= st '[dep-var X])
             (= st '[dep-var Y]))
       ['dep-var (symbol (str m))]
       (if (or (= st '[ind-var X])
               (= st '[ind-var Y]))
         ['ind-var (symbol (str m))]                        ;why do we have symbols in derivations?
         (apply vector (for [x st]
                         (normalize-variables x m)))))
     st)))</pre></td></tr><tr><td class="docs"><p>checks whether the statement of task is a it is a type of ((&amp;/,precondition,operation) =/> consequent) statement,
  also returning the unification map used for the unification between the form and the statement.</p>
</td><td class="codes"><pre class="brush: clojure">(defn precondition-operation-consequent-statement
  [task] ;(doseq [op ['pred-impl '&lt;/&gt;]])
  (let [precondition-op-forms ['[pred-impl [seq-conj [seq-conj ?precondition ?interval1 ?operation] ?interval2] ?goal]]
        additional-condition (fn [z] (and (not= (second z) nil)
                                          (operation? ((second z) '?operation))
                                          (not (operation? ((second z) '?precondition)))
                                          (interval? ((second z) '?interval1))
                                          (not (negation-of-operation? ((second z) '?precondition)))
                                          (not (operation? ((second z) '?goal)))
                                          (not (negation-of-operation? ((second z) '?goal)))))]
    (first
      (filter additional-condition
             (for [form precondition-op-forms]
               [task (unify form (:statement task))])))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#nal.test_utils" name="nal.test_utils"><h1 class="project-name">nal.test_utils</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns nal.test_utils
  (:require [clojure.set :as set]
            [narjure.defaults :refer :all]
            [nal.term_utils :refer :all]
            [narjure.narsese :refer :all]
            [nal.deriver :refer :all]))</pre></td></tr><tr><td class="docs"><p>Checks whether the truth values are equal with allowing up to truth-tolerance of difference in each component.</p>
</td><td class="codes"><pre class="brush: clojure">(def truth-tolerance 0.005)
(defn truth-equal?
  ([s1 s2]
   (and (truth-equal? first s1 s2)
        (truth-equal? last s1 s2)))
  ([f s1 s2]
   (&lt; (Math/abs (- (f (:truth s1))
                   (f (:truth s2))))
      truth-tolerance)))</pre></td></tr><tr><td class="docs"><p>Create all conclusions based on two Narsese premise strings</p>
</td><td class="codes"><pre class="brush: clojure">(defn conclusions
  ([p1 p2]
   (let [parsed-p1 (parse2 p1)
         parsed-p2 (parse2 p2)]
     (inference parsed-p1 parsed-p2))))</pre></td></tr><tr><td class="docs"><p>Checks whether a certain expected conclusion is derived</p>
</td><td class="codes"><pre class="brush: clojure">(defn derived                                               ;must derive single step (no tick parameter), no control dependency
  ([p1 p2 clist]
   (dosync
     (use-counter-reset)                                    ;making sure each testcases starts with zero seed
     (let [parsed-p1 (parse2 p1)]
       (every? (fn [c] (let [parsed-c (parse2 c)]
                         (some #(and (= (:statement %) (:statement parsed-c))
                                     (= (:occurrence %) (:occurrence parsed-c))
                                     (or (= (:task-type parsed-p1) :question)
                                         (= (:task-type parsed-p1) :quest)
                                         (truth-equal? % parsed-c)))
                               (conclusions p1 p2)))) clist)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.actor.utils" name="narjure.actor.utils"><h1 class="project-name">narjure.actor.utils</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.actor.utils
  (:require
    [co.paralleluniverse.pulsar
     [core :refer [defsfn]]
     [actors :refer [set-state! state receive ! self register!]]]
    [taoensso.timbre :refer [debug]]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn create-actor
  ([name handlers]
   (create-actor name  {} handlers))
  ([name doc handlers]
   (create-actor name doc {} handlers))
  ([name doc default-state handlers]
   (let [aname (keyword name)
         has-args (and (vector? default-state)
                       (symbol? (first default-state)))]
     `(defsfn ~name ~doc ~(if has-args default-state [])
        ~@(when (not= 'concept name) [`(register! ~aname @self)])
        (set-state! ~(if has-args
                       (first default-state)
                       default-state))
        (loop []
          (let [msg# (receive)
                handler# (get ~handlers (first msg#) :unhandled)]
            (if (= :unhandled handler#)
              (debug ~name (str &quot;unhandled msg:&quot; msg#))
              (set-state! (handler# msg# @state)))
            (recur)))))))</pre></td></tr><tr><td class="docs"><p>Wraps handler which generates side effect. Returns state without changes.</p>
</td><td class="codes"><pre class="brush: clojure">(defn side-effect!
  [handler]
  (fn [message state]
    (handler message state)
    state))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmacro defactor [&amp; args]
  (apply create-actor args))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn read-one
  [r]
  (try
    (read r)
    (catch java.lang.RuntimeException e
      (if (= &quot;EOF while reading&quot; (.getMessage e))
        ::EOF
        (throw e)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn read-seq-from-file
  [path]
  (with-open [r (java.io.PushbackReader. (clojure.java.io/reader path))]
    (binding [*read-eval* false]
      (doall (take-while #(not= ::EOF %) (repeatedly #(read-one r)))))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.bag" name="narjure.bag"><h1 class="project-name">narjure.bag</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.bag
  (:require [avl.clj :as avl]
            [co.paralleluniverse.pulsar
             [actors :refer [shutdown!]]
             [core :refer [join]]]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defprotocol Bag
  (add-element
    ; Adds element to bag, removes element with lowest priority if bag is full.
    [_ element])
  (get-by-index
    ; Returns tuple of element and updated bag. If element with such index
    ; doesn't exist throws IndexOutOfBoundsException.
    [_ index])
  (lookup-by-index
    ; Returns element without changing bag. If element with such index
    ; doesn't exist throws IndexOutOfBoundsException.
    [_ index])
  (get-by-id
    ; Returns tuple of element and updated bag. If element with such id
    ; doesn't exist returns tuple of nil and bag without any changes.
    [_ id])
  (pop-element
    ; Returns tuple of element and updated bag. If bag is empty returns tuple
    ; of nil and bag without any changes.
    [_])
  (update-element
    ; Replaces entrie with the same id.
    [_ element])
  (count-elements [_])
  (exists?
    ; Returns true if bag contains element with id.
    [_ id]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn el [id priority]
  {:id       id
   :priority priority})</pre></td></tr><tr><td class="docs"><p>DefaultBag consist of the next elements:
1) priority-index. Sortet set which contains entries like
{:id 1 :priority 0.9}, sotred by priority. It provides access by index,
and is used to find id of entry by its index
2) elements-map contains all elements mapped by their ids
3) capacity. Limit of elemts inside the bag, when bag is full elements
with lowest priority will be removed on addition</p>
</td><td class="codes"><pre class="brush: clojure">(defrecord DefaultBag [priority-index elements-map capacity]
  Bag
  (add-element [bag {:keys [id priority] :as element}]
    &quot;Adds a bag element to the bag&quot;
    (let [cnt (count priority-index)]
      (if (exists? bag id)
        (update-element bag element)
        (if (&gt;= cnt capacity)
          (if (&lt;= (:priority (nth priority-index (dec cnt)));if same priority, still prefer the new one.
                  priority)                                ;if new element has lower priority than the lowest,
            (let [[_ bag'] (pop-element bag)]               ;then don't even attempt to add the new element.
              (add-element bag' element))
            bag)
          (let [priority-index' (conj priority-index (el id priority))
                element-map' (assoc elements-map id element)]
            (-&gt;DefaultBag priority-index' element-map' capacity))))))
  (get-by-index [_ index]
    &quot;Returns an element by its index&quot;
    (let [{:keys [id] :as element} (nth priority-index index)
          priority-index' (disj priority-index element)
          element' (elements-map id)
          element-map' (dissoc elements-map id)]
      [element' (-&gt;DefaultBag priority-index' element-map' capacity)]))
  (lookup-by-index [_ index]
    (let [{:keys [id] :as element} (nth priority-index index)
          element' (elements-map id)]
      [element']))
  (get-by-id [bag id]
    &quot;returns an element by the element id&quot;
    (if-let [{:keys [priority] :as element'} (elements-map id)]
      (let [priority-index' (disj priority-index (el id priority))
            element-map' (dissoc elements-map id)]
        [element' (-&gt;DefaultBag priority-index' element-map' capacity)])
      [nil bag]))
  (pop-element [bag]
    &quot;Removes the priority-wise worst element in the bag (returning a new bag of course).&quot;
    (let [cnt (count priority-index)]
      (if (pos? cnt)
        (let [{:keys [id] :as element} (nth priority-index (dec cnt))
              priority-index' (disj priority-index element)
              element' (elements-map id)
              ref (:ref element')
              elements-map' (dissoc elements-map id)]
          (elements-map id)
          (when ref ;TODO disable logging for this actor so that this can be enabled again
            (shutdown! ref))             ;shutdown concept actor
          [element' (-&gt;DefaultBag priority-index' elements-map' capacity)])
        [nil bag])))
  (update-element [_ {priority' :priority
                      :keys     [id]
                      :as       element'}]
    &quot;Updating an existing item in the bag.&quot;
    (let [priority (get-in elements-map [id :priority])
          elements-map' (assoc elements-map id element')]
      (if (= priority' priority)
        (-&gt;DefaultBag priority-index elements-map' capacity)
        (let [priority-index' (-&gt; priority-index
                                  (disj (el id priority))
                                  (conj (el id priority')))]
          (-&gt;DefaultBag priority-index' elements-map' capacity)))))
  (count-elements [_] (count priority-index))
  (exists? [_ id] (contains? elements-map id)))</pre></td></tr><tr><td class="docs"><p>Compares elements. If priority of elements is equal, compares the hashes of
  the ids. It is done to allow bag to contain elements with equal priority.</p>
</td><td class="codes"><pre class="brush: clojure">(defn compare-elements
  [{p1 :priority id1 :id}
   {p2 :priority id2 :id}]
  (if (= p1 p2)
    (&gt; (hash id1) (hash id2))
    (and (&gt; p1 p2) (not= id1 id2))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn default-bag
  ([] (default-bag 50))
  ([capacity]
   (-&gt;DefaultBag (avl/sorted-set-by compare-elements) {} capacity)))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.budget-functions" name="narjure.budget-functions"><h1 class="project-name">narjure.budget-functions</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.budget-functions
  (:require
    [nal
     [term_utils :refer [precondition-operation-consequent-statement]]]
    [nal.deriver
     [truth :refer [expectation t-or t-and w2c]]]
    [narjure
     [defaults :refer :all]
     [global-atoms :refer :all]
     [control-utils :refer [round2]]
     [debug-util :refer :all]]))</pre></td></tr><tr><td class="docs"><p>The task quality judged by its truth.</p>
</td><td class="codes"><pre class="brush: clojure">(defn truth-to-quality
  [t]
  (let [exp (expectation t)
        positive-truth-bias 0.75]
    exp #_(max exp (* (- 1.0 exp) positive-truth-bias))))</pre></td></tr><tr><td class="docs"><p>Occurrence budget penalty. Currently not used as forgetting seems to suffice.</p>
</td><td class="codes"><pre class="brush: clojure">(defn occurrence-penalty-tr
  [occ]
  (let [k 0.0001]
    (if (= occ :eternal)
      1.0
      (/ 1.0 (+ 1.0 (* k (Math/abs (- @nars-time occ))))))))</pre></td></tr><tr><td class="docs"><p>The highest desire value in respect to current nars-time.</p>
</td><td class="codes"><pre class="brush: clojure">(defn highest-desire-in-respect-to-now
  [concept-term]
  (:truth (:strongest-desire-about-now ((:elements-map @c-bag) concept-term)))) ;also projected to now!!</pre></td></tr><tr><td class="docs"><p>also projected to now!!</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>returns a increased budget for statements of structural interest, mainly for experiments.</p>
</td><td class="codes"><pre class="brush: clojure">(defn structural-reward-budget
  [budget derived-task]
  (let [not-matched-or-not-desired-budget [(* (first budget) 0.8) (second budget) (nth budget 2)]
        match (second (precondition-operation-consequent-statement derived-task))]
    (if (and (:truth derived-task)
             match)
      (do
        (let [goal (match '?goal)
              precondition (match '?precondition)
              goal-desire (highest-desire-in-respect-to-now goal)]
          ;(println (str &quot;2: &quot; goal))
          (if (= precondition goal)
            nil
            (if goal-desire
              (let [quality (t-or (t-or (expectation (:truth derived-task))
                                        (nth budget 2))
                                       (t-or (second goal-desire)
                                             (t-or (/ 1.0 (:sc derived-task))
                                                   0.3)))] ;TODO see goal-processor (unify)
                (do
                  (println &quot;INCREASED DERIVED BUDGET&quot;)
                  (println (narsese-print (:statement derived-task)) &quot; &quot; (:truth derived-task) &quot; &quot; (:occurrence derived-task))
                  [(max (first budget) quality) #_(max (first budget) quality)
                   (second budget) #_(max (second budget) 0.9)
                   (t-or 0.6 (t-or (nth budget 2) (/ 1.0 (:sc derived-task))))]))
              not-matched-or-not-desired-budget))))
      not-matched-or-not-desired-budget))                   ;tODO too radical)</pre></td></tr><tr><td class="docs"><p>The budget of a by general inference derived task.</p>
</td><td class="codes"><pre class="brush: clojure">(defn derived-budget
  [task derived-task]
  (when (&lt; (:sc derived-task) @max-term-complexity)
    (let [durability (/ (second (:budget task)) (:sc derived-task))
          truth-quality (if (:truth derived-task) (truth-to-quality (:truth derived-task))
                                                  0.0)
          priority (/ (* (t-or truth-quality (first (:budget task)))
                         (occurrence-penalty-tr (:occurrence derived-task)))
                      (/ (:sc derived-task) 1.0))
          rescale-factor 0.1 ;should probably not above input belief quality!
          quality (* priority
                     rescale-factor)]
      (structural-reward-budget [priority durability quality] derived-task))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.control-utils" name="narjure.control-utils"><h1 class="project-name">narjure.control-utils</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.control-utils
  (:require
    [narjure.bag :as b]
    [narjure.defaults :refer :all]
    [narjure.global-atoms :refer :all]
    [clojure.math.numeric-tower :as math]))</pre></td></tr><tr><td class="docs"><p>Round a double to the given precision (number of significant digits)</p>
</td><td class="codes"><pre class="brush: clojure">(defn round2
  [precision d]
  (let [factor (Math/pow 10 precision)]
    (/ (Math/round (* d factor)) factor)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def concept-selection-parameter 1.5)
(def task-selection-parameter 1)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn selection-fn-new
  [count]
  (Math/abs (- (* (+ (rand) (rand)) count) count)))</pre></td></tr><tr><td class="docs"><p>An item selection bag curve.</p>
</td><td class="codes"><pre class="brush: clojure">(defn selection-fn #_-old
  [count]
  (- (Math/ceil (* (math/expt (rand) concept-selection-parameter) count)) 1))</pre></td></tr><tr><td class="docs"><p>An item selection bag curve.</p>
</td><td class="codes"><pre class="brush: clojure">(defn selection-fn2
  [bag concept-priority]
  (let [count (b/count-elements bag)
        selection-parameter' (+ 1.0 (* concept-priority task-selection-parameter))
        i (- (Math/ceil (* (math/expt (rand) selection-parameter') count)) 1)]
    i))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn forget-element [el]
  &quot;Forget an element by its durability.&quot;
  (let [budget (:budget (:task el))
        new-priority (* (:priority el) (second budget))
        new-budget  [new-priority (second budget)]]
    (assoc el :priority new-priority
              :task (assoc (:task el) :budget new-budget))))</pre></td></tr><tr><td class="docs"><p>For merging evidence trails.</p>
</td><td class="codes"><pre class="brush: clojure">(defn make-ev-helper
  [e2 e1 sofar]
  (let [r1 (first e1)
        r2 (first e2)]
    (case [(= nil r1) (= nil r2)]
      [true true] sofar
      [true false] (make-ev-helper [] (rest e2) (concat [r2] sofar))
      [false true] (make-ev-helper (rest e1) [] (concat [r1] sofar))
      [false false] (make-ev-helper (rest e1) (rest e2) (concat [r1] [r2] sofar)))))</pre></td></tr><tr><td class="docs"><p>Merge evidence trails.</p>
</td><td class="codes"><pre class="brush: clojure">(defn make-evidence
  [e1 e2]
  (take max-evidence (reverse (make-ev-helper e1 e2 []))))</pre></td></tr><tr><td class="docs"><p>Check whether the evidental bases have an overlap.</p>
</td><td class="codes"><pre class="brush: clojure">(defn non-overlapping-evidence?
  [e1 e2]
  (empty? (clojure.set/intersection (set e1) (set e2))))</pre></td></tr><tr><td class="docs"><p>select n concepts from c-bag ensuring the same concept is not selected twice</p>
</td><td class="codes"><pre class="brush: clojure">(defn select-concepts-rec
  [count n bag selected]
  (if (and (pos? n) (pos? count))
    (let [[element bag'] (b/get-by-index bag (selection-fn-new count))
          selected' (conj selected element)]
      (select-concepts-rec (dec count) (dec n) bag' selected'))
    selected))</pre></td></tr><tr><td class="docs"><p>wrapper for: select-concepts-rec
   select n concepts from c-bag ensuring the same concept is not selected twice</p>
</td><td class="codes"><pre class="brush: clojure">(defn select-concepts
  [n bag]
  (let [count (b/count-elements bag)]
    (select-concepts-rec count n bag [])))</pre></td></tr><tr><td class="docs"><p>Is the priority above min. threshold?</p>
</td><td class="codes"><pre class="brush: clojure">(defn sufficient-priority?
  [selected]
  (&gt; (:priority selected) priority-threshold))</pre></td></tr><tr><td class="docs"><p>Get the concept reference from a term.</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-ref-from-term
  [term]
  (:ref ((:elements-map @c-bag) term)))</pre></td></tr><tr><td class="docs"><p>Is the task a belief?</p>
</td><td class="codes"><pre class="brush: clojure">(defn belief?
  [task]
  (= (:task-type task) :belief))</pre></td></tr><tr><td class="docs"><p>Is the task a goal?</p>
</td><td class="codes"><pre class="brush: clojure">(defn goal?
  [task]
  (= (:task-type task)) :goal)</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.core" name="narjure.core"><h1 class="project-name">narjure.core</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.core
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [immutant.scheduling :refer :all]
    [narjure.global-atoms :refer :all]
    [narjure.memory-management
     [concept-manager :refer [concept-manager]]
     [forgettor :refer [forgettor]]
     [task-dispatcher :refer [task-dispatcher]]]
    [narjure.general-inference
     [concept-selector :refer [concept-selector]]
     [general-inferencer :refer [general-inferencer]]
     [inference-request-router :refer [inference-request-router]]]
    [narjure.perception-action
     [operator-executor :refer [operator-executor]]
     [sentence-parser :refer [sentence-parser]]
     [derived-load-reducer :refer [derived-load-reducer]]
     [task-creator :refer [task-creator lastevent]]]
    [narjure.narsese :refer [parse2]]
    [taoensso.timbre :refer [info set-level!]]
    [narjure.bag :as b]
    [narjure.defaults :refer :all]
    [narjure.debug-util ])
  (:refer-clojure :exclude [promise await])
  (:import (ch.qos.logback.classic Level)
           (org.slf4j LoggerFactory)
           (java.util.concurrent TimeUnit))
  (:gen-class))</pre></td></tr><tr><td class="docs"><p>Apply an inference tick</p>
</td><td class="codes"><pre class="brush: clojure">(defn inference-tick
  []                                     ;inference-tick-interval is fast enough compared to system-tick-interval
  (cast! (whereis :concept-selector) [:inference-tick-msg]))</pre></td></tr><tr><td class="docs"><p>Apply an system tick</p>
</td><td class="codes"><pre class="brush: clojure">(defn system-tick
  []
  (cast! (whereis :task-creator) [:system-time-tick-msg])
  (cast! (whereis :derived-load-reducer) [:system-time-tick-msg])
  (cast! (whereis :forgettor) [:system-time-tick-msg]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn sentence-tick []
  (cast! (whereis :sentence-parser) [:narsese-string-msg
                                     (format &quot;&lt;%s--&gt;%s&gt;.:|10|:&quot;
                                             (rand-nth [&quot;a&quot; &quot;b&quot; &quot;c&quot; &quot;d&quot; &quot;e&quot; &quot;f&quot; &quot;g&quot;])
                                             (rand-nth [&quot;h&quot; &quot;p&quot; &quot;j&quot; &quot;k&quot; &quot;l&quot; &quot;m&quot; &quot;n&quot;]))]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn prn-ok [msg interval] (info (format &quot;\t[OK] %s (%d ms)&quot; msg interval)))</pre></td></tr><tr><td class="docs"><p>Start all relevant NARS timers.</p>
</td><td class="codes"><pre class="brush: clojure">(defn start-timers
  []
  (info &quot;Initialising system timers...&quot;)
  (schedule inference-tick {:in    @inference-tick-interval
                            :every @inference-tick-interval})
  (prn-ok :inference-timer @inference-tick-interval)
  (schedule system-tick {:every @system-tick-interval})
  (prn-ok :system-timer @system-tick-interval)
  ;uncomment following two line to auto generate input sentences
  ;(schedule sentence-tick {:every sentence-tick-interval})
  ;(prn-ok :sentence-timer)
  (info &quot;System timer initialisation complete.&quot;))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn disable-third-party-loggers []
  (doseq [logger [&quot;co.paralleluniverse.actors.behaviors.ServerActor&quot;
                  &quot;co.paralleluniverse.actors.JMXActorMonitor&quot;
                  &quot;org.quartz.core.QuartzScheduler&quot;
                  &quot;co.paralleluniverse.actors.LocalActorRegistry&quot;
                  &quot;co.paralleluniverse.actors.ActorRegistry&quot;
                  &quot;org.projectodd.wunderboss.scheduling.Scheduling&quot;]]
    (.setLevel (LoggerFactory/getLogger logger) Level/ERROR)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn setup-logging []
  (set-level! :debug)
  (disable-third-party-loggers))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def child-specs
  #(list
    [&quot;forgettor&quot; :permanent 5 5 :sec 100 (forgettor)]
    [&quot;0&quot; :permanent 5 5 :sec 100 (inference-request-router)]
    [&quot;1&quot; :permanent 5 5 :sec 100 (derived-load-reducer)]
    [&quot;2.0&quot; :permanent 5 5 :sec 100 (general-inferencer :ge0)]
    [&quot;2.1&quot; :permanent 5 5 :sec 100 (general-inferencer :ge1)]
    [&quot;2.2&quot; :permanent 5 5 :sec 100 (general-inferencer :ge2)]
    [&quot;2.3&quot; :permanent 5 5 :sec 100 (general-inferencer :ge3)]
    [&quot;2.4&quot; :permanent 5 5 :sec 100 (general-inferencer :ge4)]
    [&quot;3&quot; :permanent 5 5 :sec 100 (concept-selector)]
    [&quot;4&quot; :permanent 5 5 :sec 100 (concept-manager)]
    [&quot;5&quot; :permanent 5 5 :sec 100 (task-dispatcher)]
    [&quot;6&quot; :permanent 5 5 :sec 100 (task-creator)]
    [&quot;7&quot; :permanent 5 5 :sec 100 (operator-executor)]
    [&quot;8&quot; :permanent 5 5 :sec 100 (sentence-parser)]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def sup (atom '()))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn run []
  (reset! lastevent nil)
  (reset! max-term-complexity max-term-complexity-init)
  (info &quot;reset question filter&quot;)
  (reset! last-qu-answers [])
  (info &quot;Resetting concepts bagss:&quot;)
  (reset! c-bag (b/default-bag max-concepts))
  (info &quot;c-bag count: &quot; (b/count-elements @c-bag))
  ;(reset! e-bag (b/default-bag max-events))
  ;(info &quot;e-bag count: &quot; (b/count-elements @e-bag))
  (info &quot;Reset system Parameters:&quot;)
  (reset! nars-id -1)
  (info &quot;nars-id: &quot; @nars-id)
  (reset! nars-time 0)
  (info &quot;nars-time: &quot; @nars-time)
  (setup-logging)
  (info &quot;NARS initialising...&quot;)
  (start-timers)
  (reset! output-display '())
  (reset! sup (spawn (supervisor :all-for-one child-specs)))
  ; update user with status
  (info &quot;NARS initialised.&quot;))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn stop-timers []
  (stop))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn shutdown []
  (info &quot;Shutting down actors...&quot;)
  ; cancel schedulers
  (stop-timers)
  (shutdown! @sup)
  ;(Thread/sleep 3000)
  (info &quot;System shutdown complete.&quot;))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(run)</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.debug-util" name="narjure.debug-util"><h1 class="project-name">narjure.debug-util</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.debug-util
  (:require [narjure.global-atoms :refer :all]
            [clojure.string :as str]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def debug-messages 21)</pre></td></tr><tr><td class="docs"><p>Limit a string to cnt elements</p>
</td><td class="codes"><pre class="brush: clojure">(defn limit-string
  [st cnt]
  (subs st 0 (min (count st) cnt)))</pre></td></tr><tr><td class="docs"><p>Prints out a statement in Narsese-representation.</p>
</td><td class="codes"><pre class="brush: clojure">(defn narsese-print
  ([st]
    (narsese-print st false))
  ([st dictparent]
  (let [beautify (fn [co]
                   (case co
                     nil &quot;nil&quot;
                     pred-impl &quot;=/&gt;&quot;
                     retro-impl &quot;=\\&gt;&quot;
                     ext-inter &quot;&amp;&quot;
                     int-dif &quot;~&quot;
                     ext-image &quot;/&quot;
                     int-image &quot;\\&quot;
                     conj &quot;&amp;&amp;&quot;
                     seq-conj &quot;&amp;/&quot;
                     (let [outp (str co)]
                       (if (clojure.string/starts-with? outp &quot;op_&quot;)
                         (clojure.string/replace outp &quot;op_&quot; &quot;^&quot;)
                         outp))))]
    (if (coll? st)
      (let [isvector (vector? st)
            isdict (map? st)
            cop (first st)
            [left right] (case cop
                           ext-set [&quot;{&quot; &quot;}&quot;]
                           int-set [&quot;[&quot; &quot;]&quot;]
                           --&gt; [&quot;&lt;&quot; &quot;&gt;&quot;]
                           &lt;-&gt; [&quot;&lt;&quot; &quot;&gt;&quot;]
                           ==&gt; [&quot;&lt;&quot; &quot;&gt;&quot;]
                           pred-impl [&quot;&lt;&quot; &quot;&gt;&quot;]
                           =|&gt; [&quot;&lt;&quot; &quot;&gt;&quot;]
                           retro-impl [&quot;&lt;&quot; &quot;&gt;&quot;]
                           &lt;=&gt; [&quot;&lt;&quot; &quot;&gt;&quot;]
                           &lt;|&gt; [&quot;&lt;&quot; &quot;&gt;&quot;]
                           &lt;/&gt; [&quot;&lt;&quot; &quot;&gt;&quot;]
                           [&quot;(&quot; &quot;)&quot;])
            syll-cop ['--&gt; '&lt;-&gt; '==&gt; '=|&gt;
                      'pred-impl 'retro-impl
                      '&lt;=&gt; '&lt;|&gt; '&lt;/&gt;]
            seperator (if (or dictparent
                              (some #{cop} syll-cop)
                              (not isvector))
                        &quot; &quot;
                        &quot;,&quot;)
            infixprint (if (some #{cop} syll-cop)
                         [(second st) (first st) (nth st 2)]
                         st)
            var-and-ival (fn [st]
                           (if (= (first st) :interval)
                             [(str &quot;i&quot; (second st))]
                             (if (= (first st) 'dep-var)
                               [(str &quot;#&quot; (second st))]
                               (if (= (first st) 'ind-var)
                                 [(str &quot;$&quot; (second st))]
                                 (if (= (first st) 'qu-var)
                                   [(str &quot;?&quot; (second st))]
                                   st)))))
            ivar-val (var-and-ival infixprint)
            [leftres rightres] (if (and (= ivar-val infixprint)
                                        (not dictparent))
                                 [left right]
                                 [&quot;&quot; &quot;&quot;])
            res (if (or (= (first ivar-val) 'ext-set)
                        (= (first ivar-val) 'int-set))
                  (rest ivar-val)
                  ivar-val)]
        (str leftres
             (apply str (for [x res]
                          (if (= x (first res))
                            (narsese-print x isdict)
                            (str seperator (narsese-print x isdict)))))
             rightres))
      (str (beautify st))))))</pre></td></tr><tr><td class="docs"><p>Debuglogger as used by all actor components mainly for (Lense) display purposes.</p>
</td><td class="codes"><pre class="brush: clojure">(defn debuglogger
  ([display message]
    (debuglogger (atom &quot;&quot;) display message))
  ([filter display message]
   (if (&gt; debug-messages 0)
     (swap! display (fn [d] (let [msg (narsese-print message)]
                              (if (every? (fn [x] (.contains msg x))
                                          (str/split (deref filter) #&quot;\n&quot;))
                                (if (&lt; (count d) debug-messages)
                                 (conj d [(limit-string msg 750) &quot;§&quot;])
                                 (conj (drop-last d) [(limit-string msg 750) &quot;§&quot;]))
                                d)))))))</pre></td></tr><tr><td class="docs"><p>Print the punctuation of a task in ASCII representation.</p>
</td><td class="codes"><pre class="brush: clojure">(defn punctuation-print
  [task-type]
  (case task-type
    :goal &quot;!&quot;
    :quest &quot;@&quot;
    :question &quot;?&quot;
    :belief &quot;.&quot;))</pre></td></tr><tr><td class="docs"><p>Convert a task to Narsese representation.</p>
</td><td class="codes"><pre class="brush: clojure">(defn task-to-narsese
  [task]
  (let [time-print (fn [occurrence]
                     (if (= occurrence :eternal)
                       &quot;&quot;
                       (str &quot;:|&quot; (- occurrence @nars-time) &quot;|:&quot;)))
        truth-print (fn [truth]
                      (if (= truth nil)
                        &quot;&quot;
                        (str &quot;%&quot; (first truth) &quot;;&quot; (second truth) &quot;%&quot;)))]
    (str (narsese-print (:statement task))
         (punctuation-print (:task-type task))
         &quot; &quot;
         (time-print (:occurrence task))
         &quot; &quot;
         (truth-print (:truth task)))))</pre></td></tr><tr><td class="docs"><p>Output a task into the display.</p>
</td><td class="codes"><pre class="brush: clojure">(defn output-task
  [type task]
  (let [type-print (fn [t] t)]
    (debuglogger output-search output-display (str (type-print type)
                                                   &quot; &quot;
                                                   (task-to-narsese task)))))</pre></td></tr><tr><td class="docs"><p>The ID that makes solutions unique for output.</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-solution-id
  [task]
  [(:statement task) (:task-type task) (:occurrence task) (:truth task)])</pre></td></tr><tr><td class="docs"><p>Is the task an input-task?</p>
</td><td class="codes"><pre class="brush: clojure">(defn user?
  [task]
  (= (:source task) :input))</pre></td></tr><tr><td class="docs"><p>Potentially output the answer to a task, if it wasn't already.</p>
</td><td class="codes"><pre class="brush: clojure">(def max-qu-track 50)
(defn potential-output-answer
  [state task-id task solution]
  (when (user? task)
    (let [solution-id (get-solution-id solution)]
     (when (not (some #{[task-id solution-id]} @last-qu-answers))
       (reset! last-qu-answers (concat [[task-id solution-id]] @last-qu-answers))
       (while (&gt; (count @last-qu-answers) max-qu-track)
         (reset! last-qu-answers (drop-last @last-qu-answers)))
       (doseq [f @answer-handlers]
         (f task solution))
       (output-task [:answer-to (str (narsese-print (:statement task)) (punctuation-print (:task-type task)) #_&quot; c: &quot; #_concept-id)] solution)))))</pre></td></tr><tr><td class="docs"><p>For debugging purposes, allowing to add print statements for specific concepts.</p>
</td><td class="codes"><pre class="brush: clojure">(defn conditionalprint
  [state st stru]
  (when (= (:id @state) st)
    (println stru)))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.defaults" name="narjure.defaults"><h1 class="project-name">narjure.defaults</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.defaults)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def belief-frequency 1.0)
(def belief-confidence 0.9)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def truth-value
  [belief-frequency belief-confidence])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def belief-priority 0.99)
(def belief-durability 0.9)</pre></td></tr><tr><td class="docs"><p>todo clarify this</p>
</td><td class="codes"><pre class="brush: clojure">(def belief-quality 0.5)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def belief-budget
  [belief-priority belief-durability belief-quality])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def question-priority 0.9)
(def question-durability 0.9)</pre></td></tr><tr><td class="docs"><p>todo clarify this</p>
</td><td class="codes"><pre class="brush: clojure">(def question-quality 0.56)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def question-budget
  [question-priority question-durability question-quality])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def goal-confidence 0.9)
(def goal-priority 0.99)                                    ;set higher than potential quality rewards in the system (best-operation-selection, structural reinforcement)</pre></td></tr><tr><td class="docs"><p>set higher than potential quality rewards in the system (best-operation-selection, structural reinforcement)</p>
</td><td class="codes"><pre class="brush: clojure">(def goal-quality 0.567)
(def goal-durability 0.9)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def goal-budget
  [goal-priority goal-durability goal-quality])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def budgets
  {:belief belief-budget
   :question question-budget
   :goal goal-budget
   :quest question-budget})</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def c-priority 0.5)                                        ; default concept priority</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def ^{:type double} horizon 1)                             ; personality factor for evidential horizon</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def max-evidence 10)                                       ; maximum length of evidence trail</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def temporal-window-duration 1)                           ; number of system cycles to consider as concurrent</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def term-complexity-offset 11) ;todo a better budget function instead</pre></td></tr><tr><td class="docs"><p>todo a better budget function instead</p>
</td><td class="codes"><pre class="brush: clojure">(def max-term-complexity-init 10)
(def max-term-complexity (atom max-term-complexity-init))                                ; maximum number of terms and sub terms in a statement - syntactic complexity</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def priority-threshold 0.0)                              ; concepts and tasks have to be above this to be processed</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def max-concept-selections 5)                              ; don't set higher if not on a sumpercomputer, will cause trouble</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def termlink-single-sample-evidence-amount 0.01)           ; default conf for termlink truth value</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def concept-max-termlinks 10)                              ; max size of termlink bag per concept</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def max-tasks 30)                                          ; max size of task bag per concept</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def max-anticipations 10)                                   ; max size of anticipation bag per concept</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def max-concepts 250)                                     ; do not make too small (less than 50) as causes cyclic issue between task-dispatcher and concept-manager</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def max-derived-sentences 50)                              ; derived task bag capacity</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def max-derived-selections 10)                             ; max derived selections per cycle</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def max-event-selections 10)                               ; no longer used - number of events to select per cycle</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def inverse-decay-rate 10)                                        ; forgetting adjustment rate for concepts e^-lt where l = (1.0 - durabiity) / decay-rate</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def system-tick-interval-slow 136)
(def inference-tick-interval-slow 100)
(def system-tick-interval-medium 60)
(def inference-tick-interval-medium 30)
(def system-tick-interval-fast 30)
(def inference-tick-interval-fast 15)
(def system-tick-interval (atom system-tick-interval-medium))                               ;make big enough</pre></td></tr><tr><td class="docs"><p>make big enough</p>
</td><td class="codes"><pre class="brush: clojure">(def inference-tick-interval (atom inference-tick-interval-medium))
(def anticipation-scale-dependent-tolerance 4.0)            ;has to be 4 since interval rounding has to agree with time measurement in 2-power</pre></td></tr><tr><td class="docs"><p>has to be 4 since interval rounding has to agree with time measurement in 2-power</p>
</td><td class="codes"><pre class="brush: clojure">(def anticipation-disappointment-priority-gain 1.5)         ;should be &gt;=1.0 !</pre></td></tr><tr><td class="docs"><p>should be >=1.0 !</p>
</td><td class="codes"><pre class="brush: clojure">(def termlink-default-budget [0.1 0.9])
(def concept-selection-introduced-termlink-default-budget [0.1 0.3])
(def termlink-context-adaptations-speed 0.05)
(def revision-relevant-event-distance 30.0)                  ;TODO check its relation to temporal window and the parameter in projection</pre></td></tr><tr><td class="docs"><p>TODO check its relation to temporal window and the parameter in projection</p>
</td><td class="codes"><pre class="brush: clojure">(def termlink-record-size concept-max-termlinks)
(def negation-rule-priority-threshold 0.9) </pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.general-inference.concept-selector" name="narjure.general-inference.concept-selector"><h1 class="project-name">narjure.general-inference.concept-selector</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.general-inference.concept-selector
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]    [narjure.global-atoms :refer [c-bag lense-taskbags lense-termlinks]]
    [narjure.bag :as b]
    [nal.term_utils :refer [syntactic-complexity interval?]]
    [narjure.defaults :refer [max-concept-selections]]
    [clojure.math.numeric-tower :as math]
    [narjure.memory-management.concept-utils :refer [concept-observable]]
    [taoensso.timbre :refer [debug info]]
    [narjure.debug-util :refer :all]
    [narjure.control-utils :refer :all])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def aname :concept-selector)
(def display (atom '()))
(def search (atom ))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn temporal-conjunction-observable?
  [id]
  (and (sequential? id)
       (or (and (= (first id) 'seq-conj)
                (not (interval? (last id)))) ;these are for predictions
           #_(= (first id) '&amp;|))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn observable-temporal-conjunction?
  [id]  ;a temporal conjunction is observable if it is a temporal conjunction that is observable or
  (and (temporal-conjunction-observable? id) ;where each element is either a observable temporal conjunctions itself,
       (or (concept-observable id) ;observable, or an interval
         (let [cnt (count id)]
           (every? (fn [z] (or (interval? z)
                               (concept-observable z)
                               (observable-temporal-conjunction? z)))
                   (for [i (range 1 cnt)]
                     (id i))))))) ;or all components are observable</pre></td></tr><tr><td class="docs"><p>or all components are observable</p>
</td><td class="codes"></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn temporal-linkage-justified
  [id]
  (or (concept-observable id)
      (observable-temporal-conjunction? id)))</pre></td></tr><tr><td class="docs"><p> creates a term-link between last-selected concept and the currently selected concept</p>
</td><td class="codes"><pre class="brush: clojure">(defn strengthen-temporal-link
  [state selected]
  (when-let [last-selected (:last-selected state)] ;the last selected observable concept
    (when (temporal-linkage-justified (:id selected))   ; todo need to be able to link to itself here (&amp;/, a, a) is valid sequence
      (cast! (:ref selected) [:termlink-strengthen-msg [(:id last-selected)]])
      (cast! (:ref last-selected) [:termlink-strengthen-msg [(:id selected)]])))
  (when (concept-observable (:id selected)) ;one needs to be observable directly to justify linkage
    (set-state! (assoc state :last-selected selected))))</pre></td></tr><tr><td class="docs"><p>Select n concepts for inference and post
   inference-request-message to each selected
   concept</p>
</td><td class="codes"><pre class="brush: clojure">(defn inference-tick-handler
  [from [msg]]
  (doseq [[k v] @lense-taskbags]                            ;is empty if not in debug so can stay here for now since we
    (when-not (b/exists? @c-bag k)                          ;don't want mem to get full just because lense isn't running
      (swap! lense-taskbags (fn [old] (dissoc old k))) ;element doesnt exist anymore
      (swap! lense-termlinks (fn [old] (dissoc old k)))))
  ; (dotimes [n (min (b/count-elements @c-bag) 1)]
  ;one concept for inference is enough for now ^^
  (doseq [selected (select-concepts max-concept-selections @c-bag)]
    (strengthen-temporal-link @state selected)
    (when (sufficient-priority? selected)
      (cast! (:ref selected) [:inference-request-msg (:id selected)])
      (debuglogger search display (list &quot;Concept selected: &quot; [:task selected :priority (:priority selected)])))))</pre></td></tr><tr><td class="docs"><p>Initialises actor:
      registers actor and sets actor state</p>
</td><td class="codes"><pre class="brush: clojure">(defn initialise
  [aname actor-ref]
  (reset! display '())
  (register! aname actor-ref)
  (set-state! {}))</pre></td></tr><tr><td class="docs"><p>Identifies message type and selects the correct message handler.
   if there is no match it generates a log message for the unhandled message </p>
</td><td class="codes"><pre class="brush: clojure">(defn msg-handler
  [from [type :as message]]
  ;(debuglogger display message) since tick is uninteresting we use what is selected
  (case type
    :inference-tick-msg (inference-tick-handler from message)
    (debug aname (str &quot;unhandled msg: &quot; type))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn concept-selector []
  (gen-server
    (reify Server
      (init [_] (initialise aname @self))
      (terminate [_ cause] #_(info (str aname &quot; terminated.&quot;)))
      (handle-cast [_ from id message] (msg-handler from message)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.general-inference.general-inferencer" name="narjure.general-inference.general-inferencer"><h1 class="project-name">narjure.general-inference.general-inferencer</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.general-inference.general-inferencer
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [nal
     [deriver :refer [inference]]
     [term_utils :refer [syntactic-complexity operation? interval?]]]
[nal.deriver :refer [inference]]
[taoensso.timbre :refer [debug info]]
    [narjure.memory-management.concept-utils :refer [concept-priority]]
[narjure
     [debug-util :refer :all]
     [budget-functions :refer [derived-budget]]
     [defaults :refer :all]
     [control-utils :refer [make-evidence non-overlapping-evidence?]]]
    [narjure.memory-management.local-inference.local-inference-utils :refer [get-task-id]])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def display (atom '()))
(def search (atom ))</pre></td></tr><tr><td class="docs"><p>Processes :do-inference-msg:
    generates derived results, budget and occurrence time for derived tasks.
    Posts derived sentences to task creator</p>
</td><td class="codes"><pre class="brush: clojure">(defn do-inference-handler
  [from [msg [task-concept-id belief-concept-id task belief debug]]]
  (try
    (when (non-overlapping-evidence? (:evidence task) (:evidence belief))
      (let [pre-filtered-derivations (inference task belief)
            filtered-derivations (filter #(not= (:statement %) (second (:parent-statement task))) pre-filtered-derivations)
            evidence (make-evidence (:evidence task) (:evidence belief))
            derived-load-reducer (whereis :derived-load-reducer)]
        (when-not (empty? evidence)
          (doseq [derived filtered-derivations]
            (let [sc (syntactic-complexity (:statement derived))
                  derived (assoc derived :sc sc)            ; required for derived-budget
                  budget (derived-budget task derived)
                  derived-task (assoc derived :budget budget
                                              :parent-statement [(get-task-id task) (:statement task)]
                                              :evidence evidence)
                  implies (fn [a b] (or (not a) b))]
              (when (and budget
                         (&lt; sc @max-term-complexity)
                         (&gt; (first budget) priority-threshold)
                         (or (not (:truth derived-task))
                             ;negation handling:
                             (implies (or ;if one is the negation of the other, then the derivation is fine if
                                          (= (:statement derived-task)
                                             ['-- (:statement task)])
                                          (= (:statement task)
                                             ['-- (:statement derived-task)]))
                                  (or (&gt; (concept-priority (:statement derived-task)) negation-rule-priority-threshold)
                                      (&lt; (first (:truth task)) 0.5)))) ;the task concept priority was high or frequency was smaller 0.5
                         (let [st (:statement derived-task)]
                           (and
                                (not (and (coll? st)   ;not allow interval to be the subject of predicate of ==&gt;
                                          (or (= (first st) 'pred-impl)
                                              (= (first st) '=|&gt;)
                                              (= (first st) '&lt;|&gt;)
                                              (= (first st) '&lt;/&gt;)
                                              (= (first st) '==&gt;)
                                              (= (first st) '&lt;=&gt;))
                                          (or (interval? (second st))
                                              (interval? (nth st 2)))))))
                         #_(coll? (:statement derived-task)))
                #_(when debug
                  (println (str &quot;|||||\n&quot; derived-task)))
                (cast! derived-load-reducer [:derived-sentence-msg [task-concept-id
                                                                    belief-concept-id
                                                                    derived-task]])))))))
    (catch Exception e (debuglogger search display (str &quot;inference error &quot; (.toString e))))))</pre></td></tr><tr><td class="docs"><p>Initialises actor:
      registers actor and sets actor state</p>
</td><td class="codes"><pre class="brush: clojure">(defn initialise
  [aname actor-ref]
  (reset! display '())
  (register! aname actor-ref))</pre></td></tr><tr><td class="docs"><p>Identifies message type and selects the correct message handler.
   if there is no match it generates a log message for the unhandled message </p>
</td><td class="codes"><pre class="brush: clojure">(defn msg-handler
  [from [type :as message]]
  (debuglogger search display message)
  (case type
    :do-inference-msg (do-inference-handler from message)
    (debug :ge (str &quot;unhandled msg: &quot; type))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn general-inferencer [aname]
  (gen-server
    (reify Server
      (init [_] (initialise aname @self))
      (terminate [_ cause] #_(info (str aname &quot; terminated.&quot;)))
      (handle-cast [_ from id message] (msg-handler from message)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.general-inference.inference-request-router" name="narjure.general-inference.inference-request-router"><h1 class="project-name">narjure.general-inference.inference-request-router</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.general-inference.inference-request-router
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [nal.deriver :refer [inference]]
    [taoensso.timbre :refer [debug info]]
    [narjure.global-atoms :refer :all]
    [narjure.debug-util :refer :all]
    [narjure.defaults :refer [priority-threshold]]
    [narjure.control-utils :refer [make-evidence]]
    [nal.deriver.truth :refer [expectation]])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def aname :inference-request-router)
(def display (atom '()))
(def search (atom ))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn get-next-routee []
  (let [routee ((:routees @state) (:next-routee @state))]
    (set-state! (update @state :next-routee #(mod (inc %) (:num-routees @state))))
    ;(println (str &quot;:routee: &quot; routee &quot; next: &quot; (:next-routee @state)))
    (whereis routee)))</pre></td></tr><tr><td class="docs"><p>Processes :do-inference-msg:
    posts msg to next routee in round robin fashion</p>
</td><td class="codes"><pre class="brush: clojure">(defn do-inference-handler
  [from message]
  (cast! (get-next-routee) message))</pre></td></tr><tr><td class="docs"><p>Identifies message type and selects the correct message handler.
   if there is no match it generates a log message for the unhandled message </p>
</td><td class="codes"><pre class="brush: clojure">(defn msg-handler
  [from [type :as message]]
  (debuglogger search display message)
  (case type
    :do-inference-msg (do-inference-handler from message)
    (debug aname (str &quot;unhandled msg: &quot; type))))</pre></td></tr><tr><td class="docs"><p>Initialises actor:
      registers actor and sets actor state</p>
</td><td class="codes"><pre class="brush: clojure">(defn initialise
  [aname actor-ref]
  (reset! display '())
  (register! aname actor-ref)
  (let [new-state {:num-routees 5
                   :next-routee 0
                   :routees [:ge0 :ge1 :ge2 :ge3 :ge4]}]
    (set-state! new-state)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn inference-request-router []
  (gen-server
    (reify Server
      (init [_] (initialise aname @self))
      (terminate [_ cause] #_(info (str aname &quot; terminated.&quot;)))
      (handle-cast [_ from id message] (msg-handler from message)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.global-atoms" name="narjure.global-atoms"><h1 class="project-name">narjure.global-atoms</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.global-atoms
  (:require
    [narjure.bag :as b]
    [narjure.defaults :refer :all]
    [nal.deriver.projection-eternalization :refer [project-eternalize-to]]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def c-bag (atom (b/default-bag max-concepts)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def nars-time (atom 0))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def nars-id (atom -1))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def output-display (atom '()))
(def output-search (atom ))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def lense-taskbags (atom {}))                                     ;mapping concept term to its task bag</pre></td></tr><tr><td class="docs"><p>mapping concept term to its task bag
this variable is purely for visualization/debugging purposes!!</p>
</td><td class="codes"></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def lense-termlinks (atom {}))                                     ;mapping concept term to its task bag</pre></td></tr><tr><td class="docs"><p>mapping concept term to its task bag
this variable is purely for visualization/debugging purposes!!</p>
</td><td class="codes"></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn lense-max-statement-confidence-projected-to-now [concept-term task-type event]
  (project-eternalize-to @nars-time (if (= task-type :goal)
     (:strongest-desire-about-now ((:elements-map @c-bag) concept-term))
     (if event
       (:strongest-belief-event-about-now ((:elements-map @c-bag) concept-term))
       (:strongest-belief-about-now ((:elements-map @c-bag) concept-term)))) @nars-time))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def answer-handlers (atom []))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def last-qu-answers (atom []))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.memory-management.concept" name="narjure.memory-management.concept"><h1 class="project-name">narjure.memory-management.concept</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.memory-management.concept
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [taoensso.timbre :refer [debug info]]
    [clojure.core.unify :refer [unifier]]
    [nal.term_utils :refer [not-statement-and-conceptid-equal
                            statement-and-conceptid-equal]]
    [nal.deriver
     [truth :refer [w2c t-or t-and confidence frequency expectation revision]]
     [projection-eternalization :refer [project-eternalize-to]]]
    [narjure
     [global-atoms :refer :all]
     [bag :as b]
     [debug-util :refer :all]
     [control-utils :refer :all]
     [defaults :refer :all]
     [projection-utils :refer [max-statement-confidence-projected-to-now]]]
    [narjure.memory-management
     [concept-utils :refer :all]
     [termlink-utils :refer :all]]
    [nal.term_utils :refer [syntactic-complexity]]
    [narjure.memory-management.local-inference
     [local-inference-utils :refer [get-task-id get-tasks]]
     [belief-processor :refer [process-belief]]
     [goal-processor :refer [process-goal]]
     [quest-processor :refer [process-quest]]
     [question-processor :refer [process-question]]])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def display (atom '()))
(def search (atom ))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn task-handler
  [from [_ [task_]]]
  (when true
    (let [foreign-penalty (if (not-statement-and-conceptid-equal (:statement task_)
                            (:id @state))
                            1.0
                            1.0)
          eternal-penalty (if (= (:occurrence task_) :eternal)
                            1.0
                            1.0)
          task (assoc task_ :budget [(* foreign-penalty eternal-penalty (first (:budget task_)))
                                     (second (:budget task_))
                                     (nth (:budget task_) 2)])]
      (debuglogger search display [&quot;task processed:&quot; task])
      (refresh-termlinks task)
      ; check observable and set if necessary
      (when-not (:observable @state)
        ;(println &quot;obs1&quot;)
        (let [{:keys [occurrence source]} task]
          (when (and (not= occurrence :eternal) (= source :input) (statement-and-conceptid-equal (:statement task) (:id @state)))
            (set-state! (assoc @state :observable true)))))
      #_(when (and (= (:task-type task) :goal)
                   (= (:statement task) '[--&gt; ballpos [int-set equal]]))
          (println &quot;concept ballpos equ exists&quot;))
      (case (:task-type task)
        :belief (process-belief state task 0)
        :goal (process-goal state task 0)
        :question (process-question state task)
        :quest (process-quest state task)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn belief-request-handler
  [from [_ [task-concept-id task]]]
  (try                                                      ;update termlinks at first
    (update-termlink (:statement task))          ;task concept here
    (catch Exception e (debuglogger search display (str &quot;belief side termlink strength error &quot; (.toString e)))))
  ;todo get a belief which has highest confidence when projected to task time
  (try
    (let [tasks (get-tasks state)
          beliefs (filter #(and (statement-and-conceptid-equal (:statement %) (:id @state))
                                (= (:task-type %) :belief)) tasks)
          projected-belief-tuples (map (fn [z] [z (project-eternalize-to (:occurrence task) z @nars-time)]) beliefs)]
      (when (not-empty projected-belief-tuples)
        (doseq [belief beliefs]
          (debuglogger search display [&quot;selected belief:&quot; belief &quot;§&quot;])
          (cast! (:inference-request-router @state) [:do-inference-msg [task-concept-id (:id @state) task belief]])))
      ;dummy? belief as &quot;empty&quot; termlink belief selection for structural inference
      (let [belief {:statement (:id @state) :task-type :question :occurrence :eternal :evidence '()}]
        (debuglogger search display [&quot;selected belief:&quot; belief &quot;§&quot;])
        (cast! (:inference-request-router @state) [:do-inference-msg [task-concept-id (:id @state) task belief]])))
    (catch Exception e (debuglogger search display (str &quot;belief request error &quot; (.toString e))))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn inference-request-handler
  [from message]
  (let [task-bag (:tasks @state)]
    (when true
      ;(println (syntactic-complexity (:id @state)))
      (when (pos? (b/count-elements task-bag))
        (let [[el] (b/lookup-by-index task-bag (selection-fn (b/count-elements task-bag)))]
          (debuglogger search display [&quot;selected inference task:&quot; el])
          (when-let [[c-id c-ref] (select-termlink-ref (:record (:task el)) (:lbudgets (:task el)))]
            (set-state!
              (assoc @state :tasks
                            (b/update-element task-bag
                                              (assoc-in el [:task :record]
                                                        (if (nil? (:record (:task el)))
                                                          [[c-id @nars-time]];;;
                                                          (if (some (fn [[id _]] (= id c-id)) (:record (:task el)))
                                                            (filter not-outdated-record-entry (:record (:task el)))
                                                            (take termlink-record-size (filter not-outdated-record-entry
                                                                                               (concat [[c-id @nars-time]]
                                                                                                       (:record (:task el)))))))))))
            (try                                                  ;update termlinks at first
              (update-termlink c-id)          ;task concept here
              (catch Exception e (debuglogger search display (str &quot;task side termlink strength error &quot; (.toString e)))))
            (cast! c-ref [:belief-request-msg [(:id @state) (:task el)]])))))))</pre></td></tr><tr><td class="docs"><p>Strenghtens the termlink between two concepts or creates it if not existing.
   A link is {key value] where key is term and value is budget [priority durability]</p>
</td><td class="codes"><pre class="brush: clojure">(defn termlink-strengthen-handler
  [from [_ [term]]]
  (try (let
         [termlinks (:termlinks @state)
          old-link-strength (when termlinks (termlinks term))
          temporal-link-bonus [0.5 0.01]
          new-link-strength (calc-link-strength term (if old-link-strength old-link-strength temporal-link-bonus))]
         (set-state! (assoc-in @state [:termlinks term] new-link-strength)))
       (catch Exception e (println &quot;termlink strenghten fatal error&quot;))))</pre></td></tr><tr><td class="docs"><p>Sends a copy of the actor state to requesting actor</p>
</td><td class="codes"><pre class="brush: clojure">(defn concept-state-handler
  [from _]
  (let [concept-state @state]
    (cast! from [:concept-state-msg concept-state])))</pre></td></tr><tr><td class="docs"><p>set concept state to value passed in message</p>
</td><td class="codes"><pre class="brush: clojure">(defn set-concept-state-handler
  [from [_ new-state]]
  (set-state! (merge @state new-state))
  (let [elements (:elements-map (:tasks new-state))]
    (set-state! (assoc @state :tasks (b/default-bag max-tasks)))
    (doseq [[_ el] elements]
      (set-state! (assoc @state :tasks (b/add-element (:tasks @state) el))))))</pre></td></tr><tr><td class="docs"><p>update cocnept budget</p>
</td><td class="codes"><pre class="brush: clojure">(defn concept-forget-handler
  [from [_ new-state]]
  (forget-tasks)
  (forget-termlinks-relative)
  (forget-termlinks-absolute)
  (update-concept-budget @state @self))</pre></td></tr><tr><td class="docs"><p>Processes :shutdown-msg and shuts down actor</p>
</td><td class="codes"><pre class="brush: clojure">(defn shutdown-handler
  [from msg]
  (set-state! {})
  (unregister!)
  (shutdown!))</pre></td></tr><tr><td class="docs"><p>Initialises actor: registers actor and sets actor state</p>
</td><td class="codes"><pre class="brush: clojure">(defn initialise
  [name]
  (set-state! {:id                       name
               :priority                 0.01
               :quality                  0.0
               :tasks                    (b/default-bag max-tasks)
               :termlinks                {}
               :anticipations            {}
               :concept-manager          (whereis :concept-manager)
               :inference-request-router (whereis :inference-request-router)
               :last-forgotten           @nars-time
               :observable               false}))</pre></td></tr><tr><td class="docs"><p>Identifies message type and selects the correct message handler.
   if there is no match it generates a log message for the unhandled message</p>
</td><td class="codes"><pre class="brush: clojure">(defn msg-handler
  [from [type :as message]]
  (when-not (= type :concept-forget-msg) (debuglogger search display message))
  (when (b/exists? @c-bag (:id @state))                     ;check concept has not been removed first
    (case type
      :termlink-strengthen-msg (termlink-strengthen-handler from message)
      :task-msg (task-handler from message)
      :link-feedback-msg (link-feedback-handler from message)
      :belief-request-msg (belief-request-handler from message)
      :inference-request-msg (inference-request-handler from message)
      :concept-state-request-msg (concept-state-handler from message)
      :set-concept-state-msg (set-concept-state-handler from message)
      :concept-forget-msg (concept-forget-handler from message)
      :shutdown (shutdown-handler from message)
      (debug (str &quot;unhandled msg: &quot; type))))
  (when (pos? debug-messages)
    ;(reset! lense-anticipations (:anticipation @state))
    (swap! lense-taskbags
           (fn [dic]
             (assoc dic (:id @state) (:tasks @state))))
    (swap! lense-termlinks
           (fn [dic]
             (assoc dic (:id @state) (:termlinks @state))))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn concept [name]
  (gen-server
    (reify Server
      (init [_] (initialise name))
      (terminate [_ cause] #_(info (str aname &quot; terminated.&quot;)))
      (handle-cast [_ from id message] (msg-handler from message)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.memory-management.concept-manager" name="narjure.memory-management.concept-manager"><h1 class="project-name">narjure.memory-management.concept-manager</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.memory-management.concept-manager
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [clojure.java.io :as io]
    [narjure.global-atoms :refer [c-bag nars-time nars-id]]
    [narjure.memory-management.concept :as c]
    [narjure.bag :as b]
    [narjure.defaults :refer [c-priority]]
    [nal.term_utils :refer [concept-term-transform]]
    [taoensso.timbre :refer [debug info]]
    [narjure.debug-util :refer :all])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def aname :concept-manager)                                ; actor name</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def display (atom '()))                                    ; for lense output</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def search (atom ))                                      ; for lense output filtering</pre></td></tr><tr><td class="docs"><p>Create a concept, for the supplied term, and add to
   the concept bag</p>
</td><td class="codes"><pre class="brush: clojure">(defn make-general-concept
  [term]
  (let [concept-ref (spawn (c/concept term))]
    (swap! c-bag b/add-element {:id term :priority c-priority :quality 0.0 :observable false :ref concept-ref})
    concept-ref))</pre></td></tr><tr><td class="docs"><p>Create a concept for each term in statement, if they dont
   exist. Then post the task back to task-dispatcher.</p>
</td><td class="codes"><pre class="brush: clojure">(defn create-concept-handler
  [from [_ [task-concept-id belief-concept-id {:keys [statement] :as task}]]]
  (doseq [term_ (:terms task)]
    (let [term (concept-term-transform term_)]
      (when-not (b/exists? @c-bag term)
        (make-general-concept term))))
  (cast! from [:task-from-cmanager-msg [task-concept-id belief-concept-id task]]))</pre></td></tr><tr><td class="docs"><p>Posts :concept-state-request-msg to each concept in c-map</p>
</td><td class="codes"><pre class="brush: clojure">(defn persist-state-handler
  [from [_ path]]
  (set-state! (assoc @state :concept-count (count @c-bag)
                            :received-states 0))
  (spit (:path @state) {:nars-time @nars-time :nars-id @nars-id})
  (doseq [[_ {c-ref :ref}] (:elements-map @c-bag)]
    (cast! c-ref [:concept-state-request-msg])))</pre></td></tr><tr><td class="docs"><p>process each :concept-state-msg by serialising the state to backing store.
   where state specifies the path of the backing store. The number of received
   states is tracked. The file is overwritten.</p>
</td><td class="codes"><pre class="brush: clojure">(defn concept-state-handler
  [from [_ concept-state]]
  (let [c-state (dissoc concept-state
                        :inference-request-router
                        :concept-manager)
        {:keys [path concept-count]} @state]
    (spit path (pr-str c-state) :append true)
    (set-state! (update @state :received-states inc))
    (when (= (:received-states @state) concept-count)
      (info aname &quot;Persisting concept state to disk complete&quot;))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn read-one
  [r]
  (try
    (read r)
    (catch java.lang.RuntimeException e
      (if (= &quot;EOF while reading&quot; (.getMessage e))
        ::EOF
        (throw e)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn read-seq-from-file
  [path]
  (with-open [r (java.io.PushbackReader. (clojure.java.io/reader path))]
    (binding [*read-eval* true]
      (doall (take-while #(not= ::EOF %) (repeatedly #(read-one r)))))))</pre></td></tr><tr><td class="docs"><p>read concept state from passed path, create concept for each 'record'
   and set the state as the 'record'</p>
</td><td class="codes"><pre class="brush: clojure">(defn load-state-handler
  [from [_ path]]
  (doseq [c-state (read-seq-from-file (:path @state))]
    (if (:nars-time c-state )
      (do
        (reset! nars-time (:nars-time c-state))
        (reset! nars-id (:nars-id c-state)))
       (cast! (make-general-concept (:id c-state)) [:set-concept-state-msg c-state]))))</pre></td></tr><tr><td class="docs"><p>Shutdown all concept actors</p>
</td><td class="codes"><pre class="brush: clojure">(defn clean-up
  []
  (doseq [[_ {actor-ref :ref}] (:elements-map @c-bag)]
    (shutdown! actor-ref)))</pre></td></tr><tr><td class="docs"><p>Identifies message type and selects the correct message handler.
   if there is no match it generates a log message for the unhandled message </p>
</td><td class="codes"><pre class="brush: clojure">(defn msg-handler
  [from [type :as message]]
  (debuglogger search display message)
  (case type
    :create-concept-msg (create-concept-handler from message)
    :persist-state-msg (persist-state-handler from message)
    :concept-state-msg (concept-state-handler from message)
    :load-state-msg (load-state-handler from message)
    (debug aname (str &quot;unhandled msg: &quot; type))))</pre></td></tr><tr><td class="docs"><p>Initialises actor: registers actor and sets actor state</p>
</td><td class="codes"><pre class="brush: clojure">(defn initialise
  [aname actor-ref]
  (reset! c/display '())                                    ;we also reset concept display here
  (reset! display '())                                      ;since concept actor startup is not
  (register! aname actor-ref)                               ;a place where it can be done
  (set-state! {:path &quot;memory.snapshot&quot;
               :concept-count 0
               :received-states 0}))</pre></td></tr><tr><td class="docs"><p>creates gen-server for concept-manager. This is used by the system supervisor</p>
</td><td class="codes"><pre class="brush: clojure">(defn concept-manager
  []
  (gen-server
    (reify Server
      (init [_] (initialise aname @self))
      (terminate [_ _] (clean-up))
      (handle-cast [_ from _ message] (msg-handler from message)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.memory-management.concept-utils" name="narjure.memory-management.concept-utils"><h1 class="project-name">narjure.memory-management.concept-utils</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.memory-management.concept-utils
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [taoensso.timbre :refer [debug info]]
    [narjure
     [global-atoms :refer :all]
     [bag :as b]
     [debug-util :refer :all]
     [control-utils :refer :all]
     [defaults :refer :all]
     [projection-utils :refer [max-statement-confidence-projected-to-now]]]
    [narjure.memory-management.local-inference
     [local-inference-utils :refer [get-task-id get-tasks]]
     [belief-processor :refer [process-belief]]
     [goal-processor :refer [process-goal]]
     [quest-processor :refer [process-quest]]
     [question-processor :refer [process-question]]]
    [nal.term_utils :refer [syntactic-complexity]]
    [nal.deriver
     [truth :refer [w2c t-or t-and confidence frequency expectation revision]]
     [projection-eternalization :refer [project-eternalize-to]]])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs"><p>Get the quality of a concept.</p>
</td><td class="codes"><pre class="brush: clojure">(defn concept-quality
  []
  (let [value (:quality ((:elements-map @c-bag) (:id @state)))]
    (if value
      value
      0.0)))</pre></td></tr><tr><td class="docs"><p>Get the priority of a concept.</p>
</td><td class="codes"><pre class="brush: clojure">(defn concept-priority
  [term]
  (let [value (:priority ((:elements-map @c-bag) term))]
    (if value
      value
      0.0)))</pre></td></tr><tr><td class="docs"><p>Check whether the concept is observable.</p>
</td><td class="codes"><pre class="brush: clojure">(defn concept-observable
  [term]
  (:observable ((:elements-map @c-bag) term)))</pre></td></tr><tr><td class="docs"><p>Task forgetting applied in the task bags.</p>
</td><td class="codes"><pre class="brush: clojure">(defn forget-task
  [el last-forgotten n]
  (let [task (:task el)
        el-time (:occurrence task)
        budget (:budget task)
        lambda (/ (- 1.0 (second budget)) inverse-decay-rate)
        temporal-distance (if (= el-time :eternal) 0.0 (Math/abs (- el-time @nars-time)))
        occurrence-decay 1.0 #_(if (= el-time :eternal) 1.0 (/ 1.0 (+ 1.0 (* temporal-distance
                                                                       temporal-distance))))
        k-quality-occurrence-decay 10000.0
        distance-for-quality (/ temporal-distance k-quality-occurrence-decay)
        occurrence-decay-for-quality (if (= el-time :eternal) 0.9 (/ 1.0 (+ 1.0 (* distance-for-quality
                                                                                   distance-for-quality))))
        new-quality (* #_occurrence-decay-for-quality (nth budget 2))
        fr (Math/exp (* -1.0 (* lambda (- @nars-time last-forgotten))))
        new-priority (max (round2 4 (* (:priority el) fr occurrence-decay))
                          new-quality) ;quality of task
        new-budget [new-priority (second budget) new-quality]]
    (let [updated-task (assoc task :budget new-budget)]
      (assoc el :priority new-priority
                :task updated-task))))</pre></td></tr><tr><td class="docs"><p>Task forgetting applied in the task bags.</p>
</td><td class="codes"><pre class="brush: clojure">(defn forget-tasks
  []
  (let [tasks (:elements-map (:tasks @state))
        last-forgotten (:last-forgotten @state)
        n (b/count-elements (:tasks @state))]
    (set-state! (assoc @state :tasks (b/default-bag max-tasks)))
    (doseq [[id el] tasks]                                 ;{ id {:staement :type :occurrence}
      (let [el' (forget-task el last-forgotten n)]
        ;(println (str &quot;forgetting: &quot; (get-in el' [:task :statement])))
        (set-state! (assoc @state :tasks (b/add-element (:tasks @state) el')))))
    (set-state! (assoc @state :last-forgotten @nars-time))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn concept-has-by-task-not-yet-recorded-link [state task]
  (let [recorded-terms (if (:record task) (map first (:record task)) [])
        links (:termlinks state)]
    (some (fn [tl-term] (not (some #{tl-term} recorded-terms)))
          (map first links))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn update-concept-budget [state, self]
  &quot;Update the concept budget&quot;
  (let [els (:elements-map (:tasks state))      ; :priority-index ok here
        n (count els)
        p (/ (/ (round2 3 (reduce + 0 (for [[id {task :task}] els] ;rec
                                        (if (concept-has-by-task-not-yet-recorded-link state task)
                                          (first (:budget task))
                                          0.0 #_(nth (:budget task) 2)))))
                (syntactic-complexity (:id state)))
             max-tasks)
        q (round2 3 (reduce + 0 (for [[id {task :task}] els] (nth (:budget task) 2))))
        k  0.9999                                             ; long term quality forgetting
        new-q 0.0 #_(if (pos? n) (* k (/ q n)) 0.0) ;already managed by tasks
        el {:id       (:id state)
            :priority (max p new-q)
            :quality new-q
            :ref      self
            :observable (:observable state)
            :strongest-belief-about-now (max-statement-confidence-projected-to-now state :belief nil)
            :strongest-desire-about-now (max-statement-confidence-projected-to-now state :goal nil)
            :strongest-belief-event-about-now (max-statement-confidence-projected-to-now state :belief :event)
            }]
    (swap! c-bag b/add-element el)))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.memory-management.forgettor" name="narjure.memory-management.forgettor"><h1 class="project-name">narjure.memory-management.forgettor</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.memory-management.forgettor
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [narjure.global-atoms :refer [c-bag]]
    [narjure.memory-management.concept :as c]
    [narjure.bag :as b]
    [narjure.defaults :refer [c-priority]]
    [taoensso.timbre :refer [debug info]]
    [narjure.debug-util :refer :all])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def aname :forgettor)                                      ; actor name</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def display (atom '()))                                    ; for lense output</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def search (atom ))                                      ; for lense output filtering</pre></td></tr><tr><td class="docs"><p>send message to each concept to forget</p>
</td><td class="codes"><pre class="brush: clojure">(defn system-time-tick-handler
  []
  (doseq [[id el] (:elements-map @c-bag)]
    (cast! (:ref el) [:concept-forget-msg []])))</pre></td></tr><tr><td class="docs"><p>Identifies message type and selects the correct message handler.
   if there is no match it generates a log message for the unhandled message </p>
</td><td class="codes"><pre class="brush: clojure">(defn msg-handler
  [from [type :as message]]
  (debuglogger search display message)
  (case type
    :system-time-tick-msg (system-time-tick-handler)
    (debug aname (str &quot;unhandled msg: &quot; type))))</pre></td></tr><tr><td class="docs"><p>Initialises actor: registers actor and sets actor state</p>
</td><td class="codes"><pre class="brush: clojure">(defn initialise
  [aname actor-ref]
  (reset! c/display '())                                    ;we also reset concept display here
  (reset! display '())                                      ;since concept actor startup is not
  (register! aname actor-ref)                               ;a place where it can be done
  (set-state! {}))</pre></td></tr><tr><td class="docs"><p>creates gen-server for forgettor. This is used by the system supervisor</p>
</td><td class="codes"><pre class="brush: clojure">(defn forgettor
  []
  (gen-server
    (reify Server
      (init [_] (initialise aname @self))
      (terminate [_ _])
      (handle-cast [_ from _ message] (msg-handler from message)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.memory-management.local-inference.belief-processor" name="narjure.memory-management.local-inference.belief-processor"><h1 class="project-name">narjure.memory-management.local-inference.belief-processor</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.memory-management.local-inference.belief-processor
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [taoensso.timbre :refer [debug info]]
    [narjure.bag :as b]
    [narjure.debug-util :refer :all]
    [narjure.control-utils :refer :all]
    [narjure.global-atoms :refer :all]
    [narjure.defaults :refer :all]
    [nal.term_utils :refer [not-statement-and-conceptid-equal
                            statement-and-conceptid-equal]]
    [narjure.perception-action.task-creator :refer [event? get-id]]
    [narjure.memory-management.local-inference.local-inference-utils :refer :all]
    [nal.term_utils :refer :all]
    [nal.deriver.truth :refer [t-or confidence frequency w2c t2-evidence-weights]]
    [nal.deriver.projection-eternalization :refer [project-eternalize-to eternalize]])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs"><p>Is the anticipation expired so that a negative disappointment event needs to be generated?</p>
</td><td class="codes"><pre class="brush: clojure">(defn expired?
  [anticipation]
  (&gt; @nars-time (:expiry anticipation)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn create-negative-confirmation-task [anticipation]
  &quot;collected input-evidence: [w+,w-]
   anticipated evidence: [wa+,wa-]
   positive evidence lack: lack=max(0,wa+ - w+)
   evidence that was not observed: [f,c]_result = [0,  w2c(positive-lack)]
   ''justified by the amount of positive evidence that was NOT observed as anticipated to be observed''&quot;
  #_(println (:truth anticipation))
  (let [budget (:budget anticipation)
        anticipated-good-evidence (max 0 (- (:positive-evidence (t2-evidence-weights (:anticipated-truth anticipation)))
                                            (:negative-evidence (t2-evidence-weights (:anticipated-truth anticipation)))))
        observed-good-evidence (max 0 (- (:positive-evidence (t2-evidence-weights (:truth anticipation)))
                                         (:negative-evidence (t2-evidence-weights (:truth anticipation)))))
        good-evidence-lack (max 0 (- anticipated-good-evidence
                                     observed-good-evidence))
        confidence-of-lack (w2c good-evidence-lack)]
    (println (str &quot;lack confidence: &quot; confidence-of-lack))
    (dissoc (assoc anticipation :task-type :belief
                                :evidence (list (get-id))
                                :truth [0.0 confidence-of-lack]
                                :budget [(t-or 0.7 (nth budget 0)) (nth budget 1) (nth budget 2)]
                                :parent-statement nil
                                :occurrence (:expiry anticipation) ;could be minus/plus anticipation tolerance later
                                :terms (termlink-subterms (:statement anticipation))
                               #_:budget #_[(min 1.0
                                             (* (first (:budget anticipation))
                                                confidence-of-lack
                                                anticipation-disappointment-priority-gain))
                                        (second (:budget anticipation))
                                        (nth (:budget anticipation) 2)])
           :expiry
            :minconfirm)))</pre></td></tr><tr><td class="docs"><p>Creates the negated negative confirmation task, the negation of the anticipated event
  in Narsese-negation representation.</p>
</td><td class="codes"><pre class="brush: clojure">(defn create-negated-negative-confirmation-task
  [neg-confirmation]
  (assoc neg-confirmation :statement ['-- (:statement neg-confirmation)] :truth (nal.deriver.truth/negation (:truth neg-confirmation) [0.0 0.0])))</pre></td></tr><tr><td class="docs"><p>Is the t
  ask observable and derived so potentially predicted?</p>
</td><td class="codes"><pre class="brush: clojure">(defn confirmable-observable?
  [task]
  (and #_(:observable @state) (not= (:occurrence task) :eternal)
       (= (:source task) :derived)))</pre></td></tr><tr><td class="docs"><p>The by anticipation disappointment created task.</p>
</td><td class="codes"><pre class="brush: clojure">(defn create-anticipation-task
  [task]
  (let [  ;example: i23 would still be i16 but i25 would be i32, border 24
          ;i13 would be i16, but i11 would be i8, border 12
        leftborder (/ (Math/abs (- (:occurrence task) @nars-time)) 4.0)
        rightborder (/ (Math/abs (- (:occurrence task) @nars-time)) 2.0)]
    (assoc task :task-type :anticipation
                :minconfirm (- (:occurrence task) leftborder) ;left side limit
               :expiry (+ (:occurrence task) rightborder))))      ;right side limit</pre></td></tr><tr><td class="docs"><p>right side limit</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>Budget change based on the satisfaction of the goal by the belief</p>
</td><td class="codes"><pre class="brush: clojure">(defn satisfaction-based-budget-change
  [state belief-task goals]
  ;filter goals matching concept content
  ;project-to task time
  ;select best ranked
  (let [projected-list
        (map (fn [a] [a (project-eternalize-to (:occurrence a) belief-task @nars-time)])
             (filter #(question-unifies (:statement %) (:statement belief-task)) goals))]
    (when (not-empty projected-list)
      (doseq [[goal belief-task-projected-to-goal] projected-list]
        (when (better-solution belief-task goal)
          ;update budget and solution
          ;(potential-output-answer state goal belief-task)
          (let [new-goal (reduced-goal-budget-by-belief goal belief-task-projected-to-goal)
                new-goal-with-solution (assoc new-goal :solution belief-task)]
            (update-task-in-tasks state new-goal-with-solution goal))
          (let [new-belief (increased-belief-budget-by-goal belief-task-projected-to-goal goal)]
            (update-task-in-tasks state (assoc belief-task :budget (:budget new-belief)) belief-task)))))))</pre></td></tr><tr><td class="docs"><p>Budget change based on the quality of the answer.</p>
</td><td class="codes"><pre class="brush: clojure">(defn answer-based-budget-change
  [state belief-task questions]
  ;filter goals matching concept content
  ;project-to task time
  ;select best ranked
  (let [projected-list
        (map (fn [a] [a (project-eternalize-to (:occurrence a) belief-task @nars-time)])
             (filter #(question-unifies (:statement %) (:statement belief-task))
                     questions))]
    (when (not-empty projected-list)
      (doseq [[question belief-task-projected-to-question] projected-list]
        (when (better-solution belief-task question)
          (potential-output-answer state (get-task-id question) question belief-task)
          ;update budget and solution
          (let [new-question (reduced-question-budget-by-belief question belief-task-projected-to-question)
                new-question-with-solution (assoc new-question :solution belief-task)]
            (update-task-in-tasks state new-question-with-solution question))
          (let [new-belief (increased-belief-budget-by-question belief-task-projected-to-question question)]
            (update-task-in-tasks state (assoc belief-task :budget (:budget new-belief)) belief-task)))))))</pre></td></tr><tr><td class="docs"><p>Whether the new task should do revision with the old one,
  see https://groups.google.com/forum/#!topic/open-nars/4uMf_kI3Etk</p>
</td><td class="codes"><pre class="brush: clojure">(defn revision-relevant-tasks
  [task old-event]
  (or (= (:occurrence task) :eternal)
      (&lt; (Math/abs (- (:occurrence task) (:occurrence old-event)))
      revision-relevant-event-distance)))</pre></td></tr><tr><td class="docs"><p>Process a belief: revise and put into the task bag, check whether it answers a question, and manage anticipations.</p>
</td><td class="codes"><pre class="brush: clojure">(defn process-belief
  [state task cnt]
    ;also allow revision in subterm concepts! this is why statement is compared to task statement, not to ID!!
  (when true #_(not (and (= (:statement task) (:id @state))
                  (:observable @state)
                  (= (:task-type task) :belief)
                  (= (:occurrence task) :eternal)))
      (let [[{existing-belief :task} _] (b/get-by-id (:tasks @state) (get-task-id task))]
        (let [processed-task (if (and existing-belief
                                    (revision-relevant-tasks task existing-belief)
                                    (non-overlapping-evidence? (:evidence task) (:evidence existing-belief)))
                             (revise task (project-eternalize-to (:occurrence task) existing-belief @nars-time))
                             task)]
           ;add revised task to bag:
           (add-to-tasks state processed-task)
           ;check if it satisfies a goal or question and change budget accordingly
           (satisfaction-based-budget-change state (:task (first (b/get-by-id (:tasks @state) (get-task-id processed-task)))) (filter #(= (:task-type %) :goal) (get-tasks state)))
           (answer-based-budget-change state (:task (first (b/get-by-id (:tasks @state) (get-task-id processed-task)))) (filter #(= (:task-type %) :question) (get-tasks state))))))
    ; processing revised anticipations
  (when (and (event? task) #_(= (:source task) :input) (belief? task))
    (when (pos? (count (:anticipations @state)))
      (doseq [[id anticipation] (:anticipations @state)]  ;{task-id task task-id2 task2}
        (when (and (= (:statement anticipation) (:statement task))
                   (&gt; (:occurrence task) (:minconfirm anticipation)))
          (let [projected-task (project-eternalize-to (:occurrence anticipation) task @nars-time)]
             ;revise anticipation and add to tasks
             (when (non-overlapping-evidence? (:evidence projected-task) (:evidence anticipation))
               #_(println (str &quot;anticipation: &quot; anticipation &quot;\nprojected task: &quot; projected-task))
               (set-state! (assoc-in @state [:anticipations id]  (revise anticipation projected-task)))))))))
  (doseq [[id anticipation] (:anticipations @state)]                                                 ;be sure to use updated anticipation
      ;generate neg confirmation for expired anticipations
      ;and add to tasks
      (when (and anticipation (expired? anticipation))
       (let [neg-confirmation (create-negative-confirmation-task anticipation) ;      ;todo review budget in create-negative - currently priority of 1.0 with parents for d and q
             negated-neg-confirmation (create-negated-negative-confirmation-task neg-confirmation)]
         (set-state! (assoc @state :anticipations (dissoc (:anticipations @state) id)))
         ;(println (str &quot;truth: &quot; neg-confirmation))
         (when (not= (:truth neg-confirmation) [0.0 0.0])
           ;add neg-confirmation to tasks bag and remove anticiptaion
           (cast! (whereis :task-dispatcher) [:task-msg [nil nil neg-confirmation]])
           (cast! (whereis :task-dispatcher) [:task-msg [nil nil negated-neg-confirmation]])
           ;hypothesis correction:
           (when (:anticipation-precondition-task neg-confirmation)
             (cast! (whereis :inference-request-router) [:do-inference-msg [nil nil (:anticipation-precondition-task neg-confirmation) neg-confirmation :belief]])
             (println &quot;hypothesis corrected!!! with task: &quot; (:anticipation-precondition-task neg-confirmation) &quot;\n&quot;
                      &quot;belief: &quot; neg-confirmation))))))
    ;when task is confirmable and observabnle
    ;add an anticipation tasks to tasks
    (when (and (= (:task-type task) :belief)
            (statement-and-conceptid-equal (:statement task)                             ;only allow anticipation with concept content
              (:id @state)))
      (when (and (confirmable-observable? task)
                 (&gt; (:occurrence task) @nars-time))
        (let [with-anticipated-truth (fn [t] (assoc t :source :derived :anticipated-truth (:truth t) :truth [0.5 0.0]))
              anticipated-task (with-anticipated-truth (create-anticipation-task task))
              anticipations (:anticipations @state)]
          (if (&lt; (count anticipations) max-anticipations)
            (do (set-state! (assoc @state :anticipations (assoc anticipations (get-anticipation-id anticipated-task) anticipated-task)))
                (println (str &quot;created anticipation: &quot;  (:anticipations @state) &quot; &quot; anticipated-task)))
            (let [[max-future-id max-future-anticipation] (apply max-key (fn [[id anticipation]] (:occurrence anticipation)) anticipations)]
              (when (&lt;= (:occurrence anticipated-task) (:occurrence max-future-anticipation))
                (set-state! (assoc @state :anticipations (assoc (dissoc anticipations max-future-id)
                                                (get-anticipation-id anticipated-task)
                                                anticipated-task)))
                (println (str &quot;created anticipation(full): &quot; anticipated-task)))))))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.memory-management.local-inference.goal-processor" name="narjure.memory-management.local-inference.goal-processor"><h1 class="project-name">narjure.memory-management.local-inference.goal-processor</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.memory-management.local-inference.goal-processor
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [taoensso.timbre :refer [debug info]]
    [narjure.debug-util :refer [narsese-print]]
    [narjure.bag :as b]
    [narjure.defaults :refer [truth-value]]
    [nal.term_utils :refer [not-statement-and-conceptid-equal
                            statement-and-conceptid-equal]]
    [nal.term_utils :refer [syntactic-complexity termlink-subterms]]
    [nal.deriver.truth :refer [intersection deduction]]
    [narjure.debug-util :refer :all]
    [narjure.control-utils :refer :all]
    [narjure.global-atoms :refer :all]
    [narjure.perception-action.task-creator :refer [get-id]]
    [clojure.core.unify :refer [unify]]
    [nal.term_utils :refer [operation? negation-of-operation? syntactic-complexity]]
    [narjure.memory-management.local-inference.local-inference-utils :refer :all]
    [nal.deriver.truth :refer [t-or frequency confidence expectation desire-strong intersection]]
    [nal.deriver.projection-eternalization :refer [project-eternalize-to]])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs"><p>Budget change based on the satisfaction of the goal by the belief</p>
</td><td class="codes"><pre class="brush: clojure">(defn satisfaction-based-budget-change
  [state goal-task beliefs]
  ;filter goals matching concept content
  ;project-to task time
  ;select best ranked
  (let [projected-list
        (map (fn [a] [a (project-eternalize-to (:occurrence goal-task) a @nars-time)])
             (filter #(question-unifies (:statement goal-task) (:statement %)) beliefs))]
    (when (not-empty projected-list)
      (doseq [[belief belief-task-projected-to-goal] projected-list]
        (when (better-solution belief goal-task)
          ;update budget and solution
          ;(potential-output-answer state goal-task belief)
          (let [new-goal (reduced-goal-budget-by-belief goal-task belief-task-projected-to-goal)
                new-goal-with-solution (assoc new-goal :solution belief)]
            (update-task-in-tasks state new-goal-with-solution goal-task))
          (let [new-belief (increased-belief-budget-by-goal belief-task-projected-to-goal goal-task)]
            (update-task-in-tasks state (assoc belief :budget (:budget new-belief)) belief)))))))</pre></td></tr><tr><td class="docs"><p>how big the truth expectation has to be in order to allow execution.</p>
</td><td class="codes"><pre class="brush: clojure">(def decision-threshold 0.5)                                ;0.6</pre></td></tr><tr><td class="docs"><p>0.6</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>only execute if desire expectation is above decision threshold</p>
</td><td class="codes"><pre class="brush: clojure">(defn execute?
  [task]
  (&gt; (expectation (:truth task)) decision-threshold))</pre></td></tr><tr><td class="docs"><p>Budget change based on the answer quality (answering quests, which are questions on desire).</p>
</td><td class="codes"><pre class="brush: clojure">(defn answer-based-budget-change
  [state goal-task quests]
  ;filter goals matching concept content
  ;project-to task time
  ;select best ranked
  (let [projected-list
        (map (fn [a] [a (project-eternalize-to (:occurrence a) goal-task @nars-time)])
             (filter #(question-unifies (:statement %) (:statement goal-task)) quests))]
    (when (not-empty projected-list)
      (doseq [[quest goal-task-projected-to-quest] projected-list]
        (when (better-solution goal-task quest)
          (potential-output-answer state (get-task-id quest) quest goal-task)
          ;update budget and solution
          (let [new-quest (reduced-quest-budget-by-goal quest goal-task-projected-to-quest)
                new-quest-with-solution (assoc new-quest :solution goal-task)]
            (update-task-in-tasks state new-quest-with-solution quest))
          (let [new-goal (increased-goal-budget-by-quest goal-task-projected-to-quest quest)]
            (update-task-in-tasks state (assoc goal-task :budget (:budget new-goal)) goal-task)))))))</pre></td></tr><tr><td class="docs"><p>Is the term an interval?</p>
</td><td class="codes"><pre class="brush: clojure">(defn interval?
  [content]
  (and (sequential? content) (= (first content) :interval)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def truth-tolerance 0.005)                                 ;TODO put to nal.deriver.truth?</pre></td></tr><tr><td class="docs"><p>TODO put to nal.deriver.truth?
&lt;(&amp;&amp;,&lt;(*,{SELF}) --> op_down>,(&amp;/,<ballpos --> [above]>,i2048)) =/> <ballpos --> [below]>>. :|12197|: %1.0;0.20954585215002955%" "</p>
</td><td class="codes"><pre class="brush: clojure">(defn best-operation-selection [beliefs goal]
  &quot;1. find all beliefs that predict the goal ''=/&gt; =|&gt;  &lt;|&gt; &lt;/&gt;''
   2. filter those with (precondition,op) =&gt; goal
   3. use the one whose precondition is highest fullfilled and statement truth is highest
     3.1 truth_A = getting the strongest truth value of the precondition of the precondition concept projected to current moment
     3.2 truth_B = get the truth value of the implication statement
     3.3 desire = desire value of goal
     3.4 execution desire expectation is: D=desire_strong(desire_strong(desire,truth_B),truth_A)
   by using the one whose expectation(D) is highest
   4. create a result operation goal task with the from the predictive statement first operation
      and evidence trail being the summary of all evidence trails
   &lt;(&amp;/,&lt;{ball} --&gt; [down]&gt;,move_up({SELF})) =/&gt; &lt;{ball} --&gt; [equal]&gt;&gt;. %0.4;09% Premise   &lt;- truth_B
    &lt;{ball} --&gt; [equal]&gt;!  Premise                                                        &lt;- desire
    |-
    (&amp;/,&lt;{ball} --&gt; [down]&gt;,move_up({SELF}))!  Desire:Deduction
    &lt;{ball} --&gt; [down]&gt;.         Premise                                        &lt;- truth_A
    |-
    move_up({SELF})!  Desire:Deduction
  for goal &lt;{ball} --&gt; [equal]&gt;!
  &lt;(&amp;/,&lt;{ball} --&gt; [up]&gt;,move_up({SELF})) =/&gt;
  &lt;{ball} --&gt; [equal]&gt;&gt;
  &lt;(&amp;/,&lt;{ball} --&gt; [up]&gt;,move_down({SELF})) =/&gt;
  &lt;{ball} --&gt; [equal]&gt;&gt;  %0.3;0.9%
  &lt;(&amp;/,&lt;{ball} --&gt; [down]&gt;,move_up({SELF})) =/&gt;
  &lt;{ball} --&gt; [equal]&gt;&gt;. %0.4;09%&quot;
  #_(when (and (= (:id @state) (:statement goal))
               (= (:occurrence goal) :eternal)
               (= (:task-type goal) :goal)
               (= (:statement goal) '[--&gt; ballpos [int-set equal]])
               (println &quot;concept ballpos equ goal processed&quot;)))
  ;1.: find all beliefs that predict the goal ''=/&gt; =|&gt;  &lt;|&gt; &lt;/&gt;''
  (when (statement-and-conceptid-equal (:statement goal)
                                       (:id @state)) #_(and (= (:occurrence goal) :eternal)
                    (= (:id @state) (:statement goal)))
    #_(when (and (= (:task-type goal) :goal)
                 (= (:statement goal) '[--&gt; ballpos [int-set equal]]))
        (println &quot;concept ballpos equ goal processed&quot;))
    (let [debugme (= (:statement goal) '[--&gt; ballpos [int-set equal]])
          println2 (fn [a] (when debugme (println a)))
          ;2. filter those with (precondition,op) =&gt; goal   ;so this one is for future improvement
          #_print1 #_(println &quot;step 1,2&quot;)
          #_blub1 #_(println2 &quot;process goal debug marker&quot;)
          precondition-op-forms ['[pred-impl [seq-conj [seq-conj ?precondition ?interval1 ?operation] ?interval2] ?goal]] ;TODO add others
          precondition-op-beliefs-and-assigment-tuple (filter
                                                        (fn [z] (and (not= (second z) nil)
                                                                     (= ((second z) '?goal) (:statement goal))
                                                                     (operation? ((second z) '?operation))
                                                                     (not (operation? ((second z) '?precondition)))
                                                                     (interval? ((second z) '?interval1))
                                                                     (not (negation-of-operation? ((second z) '?precondition)))
                                                                     (not (operation? ((second z) '?goal)))
                                                                     (not (negation-of-operation? ((second z) '?goal)))))
                                                        (for [form precondition-op-forms
                                                              belief (for [b (filter (fn [h] (= (:occurrence h) :eternal)) beliefs)] b)]
                                                          [belief (unify form (:statement belief))]))
          #_print2 #_(println (str &quot;step 3.1, 3.2\n&quot; (vec precondition-op-beliefs-and-assigment-tuple)))
          ;3. use the one whose precondition is highest fullfilled and statement truth is highest:
          ;3.1 truth_A = getting the strongest truth value of the precondition concept projected to current moment
          ;3.2 truth_B = get the truth value of the implication statement
          truth-A-B-unification-maps (for [[belief unificaton-map] precondition-op-beliefs-and-assigment-tuple]
                                       (do
                                         ;reward belief uality also for having this for control useful structure
                                         #_(println (str &quot;AND REWARDED &quot; belief))
                                         #_(println (str &quot;rewarded belief&quot; (narsese-print (:statement belief)) &quot; &quot; (:truth belief) &quot; budg: &quot; (:budget belief)))
                                         (let [budget (:budget belief)
                                               new-quality (t-or (expectation (:truth belief)) (t-or (second (:truth goal)) 0.8))] ;TODO see budget-functions (unify)
                                           #_(println (str &quot;rewarding &quot; (narsese-print (:statement belief)) &quot; &quot; (:truth belief)))
                                           #_(update-task-in-tasks state (assoc belief :budget [(max new-quality
                                                                                                   (first (:budget belief)))
                                                                                              (second (:budget belief))
                                                                                              new-quality]) ;new quality
                                                                 belief))
                                         (let [precondition (unificaton-map '?precondition)
                                               [precondition-concept bag] (b/get-by-id @c-bag precondition)
                                               strongest-belief-about-now (project-eternalize-to @nars-time (:strongest-belief-event-about-now precondition-concept) @nars-time)]
                                           (when (and precondition-concept
                                                      (:truth strongest-belief-about-now)
                                                      (:truth belief)
                                                      (&gt; (second (:truth strongest-belief-about-now)) 0.3))
                                             [(:truth strongest-belief-about-now) (:truth belief) (:evidence strongest-belief-about-now) (:evidence belief) unificaton-map belief]))))
          #_print3 #_(println (str &quot;step 3.3\n&quot; (vec truth-A-B-unification-maps)))
          ;3.3 desire = desire value of goal
          desire (:truth (project-eternalize-to @nars-time goal @nars-time))
          #_print4 #_(println (str &quot;step 3.4\n&quot; desire))
          ;3.4 execution desire expectation is: D=desire_strong(intersection(desire,truth_B),truth_A)          ;[truth-A truth-B evidence-A evidence-B unification-map debug-belief]
          D-unification-maps (for [[truth-A truth-B evidence-A evidence-B unification-map debug-belief] (filter (fn [a] a) truth-A-B-unification-maps)]
                               (do
                                 #_(println (str desire truth-B truth-A))
                                 {:D               (intersection (intersection desire truth-B) truth-A)
                                  :evidence-A      evidence-A
                                  :evidence-B      evidence-B
                                  :unification-map unification-map
                                  :debug-belief    debug-belief
                                  :truth-A         truth-A
                                  :truth-B         truth-B}))
          #_print5 #_(println (str &quot;3 get best\n&quot; (vec D-unification-maps)))
          ;by using the one whose expectation(D) is highest
          k-expectation-randomize 50.0
          best-option (apply max-key (comp (fn [a] (+ a (/ (rand) k-expectation-randomize))) expectation :D) ;not always the best one but tend to.
                             (filter (fn [z] true #_(and (non-overlapping-evidence? (:evidence goal) (:evidence-A z))
                                                         (non-overlapping-evidence? (:evidence-A z) (:evidence-B z)) ;overlap check is not transitive: A {1 2 3} B {5} C {1 2 3}
                                                         (non-overlapping-evidence? (:evidence goal) (:evidence-B z)))) D-unification-maps))
          #_print6 #_(println (str &quot;finished 3 \n&quot;best-option))
          ]
      ;4. create a result operation goal task with the from the predictive statement first operation and evidence trail being the summary of all evidence trails
      (when (and best-option
                 (best-option :D)
                 (&gt; (second (best-option :D)) truth-tolerance))
        #_(println (str &quot;had best operator option &quot; (best-option :D)))
        (let [unimap (:unification-map best-option)
              statement (unimap '?operation)
              new-task {:statement  statement
                        :truth      (best-option :D)
                        :evidence   (make-evidence (make-evidence (best-option :evidence-A) (best-option :evidence-B)) (:evidence goal))
                        :occurrence @nars-time               ;needs to be occurrence time of now since task creator leaves derived task occurrences un-touched
                        :budget     (:budget goal)
                        :task-type  :goal
                        :sc (syntactic-complexity statement)}]
          (when (&gt; (expectation (:truth new-task)) decision-threshold)
            (println (str &quot;based on &quot; (best-option :debug-belief)))
            #_(println (str &quot;operator selector sending to task-creator &quot; (:statement new-task) (:truth new-task) (expectation (:truth new-task))))
            ;create prediction for consequence:
            #_(let [
                  cont (unimap '?goal)
                  subj ['seq-conj (unimap '?precondition) (unimap '?interval1) (unimap '?operation)]]
              #_(println &quot;test1&quot;)
              (cast! (whereis :task-dispatcher)
                     [:task-msg
                      [nil ;TODO could provide link feedback
                       nil
                       {:truth                          (intersection (intersection truth-value (:truth-A best-option))
                                                                   (:truth-B best-option))
                        :budget                         (:budget goal)
                        :occurrence                     (+ @nars-time (second ((:unification-map best-option) '?interval2)))
                        :source                         :derived
                        :evidence                       (:evidence best-option)
                        :sc                             (syntactic-complexity cont)
                        :terms                          (termlink-subterms cont)
                        :solution                       nil
                        :task-type                      :belief
                        :statement                      cont
                        ;for hypothesis correction:
                        :anticipation-precondition-task {:truth      (intersection truth-value (:truth-A best-option))
                                                         :budget     (:budget goal)
                                                         :occurrence @nars-time
                                                         :source     :derived
                                                         :evidence   (list (get-id))
                                                         :task-type :belief
                                                         :statement subj
                                                         }}]])
              #_(println &quot;sent&quot;)))
          (cast! (whereis :task-creator) [:derived-sentence-msg [nil nil new-task]]))))))</pre></td></tr><tr><td class="docs"><p>Process a goal task: revise, put into the task bag, check for satisfaction and whether it
   is answered or answers a quest, and see whether it needs to execute.</p>
</td><td class="codes"><pre class="brush: clojure">(defn process-goal
  [state task cnt]
  ;group-by :task-type tasks
  (let [tasks (get-tasks state)
        groups (group-by :task-type tasks)
        goals (:goal groups)
        beliefs (:belief groups)
        quests (:quest groups)]
    ;also allow revision in subterm concepts! this is why statement is compared to task statement, not to ID!!
    (when-not (and (= (:occurrence task) :eternal)
                   (operation? (:statement task)))
      (let [related-goals (filter (fn [z] (and (same-occurrence-type z task)
                                               (= (:statement z) (:statement task)))) goals)]
        (let [total-revision (reduce (fn [a b] (if (non-overlapping-evidence? (:evidence a) (:evidence b))
                                                 (revise a (project-eternalize-to (:occurrence a) b @nars-time))
                                                 a))
                                     task (shuffle related-goals))]
          ;add revised task to bag
          (add-to-tasks state total-revision)
          ; check to see if revised or task is answer to quest and increase budget accordingly
          ;check whether it is fullfilled by belief and decrease budget accordingly
          (satisfaction-based-budget-change state (:task (first (b/get-by-id (:tasks @state) (get-task-id total-revision)))) (filter #(= (:task-type %) :belief) (get-tasks state)))
          (answer-based-budget-change state (:task (first (b/get-by-id (:tasks @state) (get-task-id total-revision)))) (filter #(= (:task-type %) :quest) (get-tasks state)))
          #_(when (and (= (:id @state) (:statement total-revision))
                       (= (:occurrence total-revision) :eternal)
                       (= (:task-type total-revision) :goal)
                       (= (:statement total-revision) '[--&gt; ballpos [int-set equal]]))
              (println &quot;concept ballpos equ goal processed&quot;))
          (try
            (best-operation-selection (filter #(= (:task-type %) :belief) (get-tasks state))
                                      (:task (first (b/get-by-id (:tasks @state) (get-task-id total-revision)))))
            (catch Exception e () #_(println (str &quot;operator selector error&quot; e)))))))
    ;best operation project goal to current time
    ; if above decision threshold then execute#
    (let [projected-goals (map #(project-eternalize-to @nars-time % @nars-time)
                               (filter #(= (:statement %) (:statement task))
                                       (filter #(= (:task-type %) :goal) ;re-getting the goals because we also want our just added goal
                                               (conj tasks task))))] ;needs new task as well
      (if (not-empty projected-goals)
        (let [possible-operations (filter #(and (operation? (:statement %)) (execute? %) (statement-and-conceptid-equal (:statement %) (:id @state))) projected-goals)
              operation (if (not-empty possible-operations)
                          (apply max-key confidence possible-operations)
                          nil)]
          (when-not (= nil operation)                   ;todo change to - when operation
            #_(println (str (:truth operation) (expectation (:truth operation))))
            ;(println (str  &quot;goal: &quot; operation))
            (when-not (:execution-evidence @state)
              (set-state! (assoc @state :execution-evidence '())))
            (when true #_(some (fn [z] (not (some #{z} (:execution-evidence @state)))) (:evidence operation))
              (cast! (whereis :operator-executor) [:operator-execution-msg operation])
              (set-state! (assoc @state :execution-evidence (take 50 (concat (:evidence operation) (:execution-evidence @state))))))))))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.memory-management.local-inference.local-inference-utils" name="narjure.memory-management.local-inference.local-inference-utils"><h1 class="project-name">narjure.memory-management.local-inference.local-inference-utils</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.memory-management.local-inference.local-inference-utils
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [taoensso.timbre :refer [debug info]]
    [narjure.bag :as b]
    [narjure.global-atoms :refer :all]
    [clojure.core.unify :refer [unify]]
    [narjure.control-utils :refer [make-evidence round2]]
    [narjure.perception-action.task-creator :refer :all]
    [nal.term_utils :refer :all]
    [nal.deriver :refer [occurrence-type]]
    [nal.deriver.truth :refer [t-and t-or frequency confidence expectation]]
    [nal.deriver.projection-eternalization :refer [project-eternalize-to]]
    [narjure.debug-util :refer :all]
    [narjure.budget-functions :refer [derived-budget]])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs"><p>Truth rounding to 2 commas</p>
</td><td class="codes"><pre class="brush: clojure">(defn truth-round
  [[f c :as truth]]
  (if (= nil truth)
    nil
    [(round2 2 f)
    (round2 2 c)]))</pre></td></tr><tr><td class="docs"><p>The ID defining when elements in the task bag need to be merged.</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-task-id
  [task] ;not using concept-term-transform would demand huge task bag size or less bias in complexity
  [(concept-term-transform (:statement task)) (:task-type task) (occurrence-type (:occurrence task))])</pre></td></tr><tr><td class="docs"><p>The ID defining when elements in the anticipations bag need to be merged.</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-anticipation-id
  [task]
  [(:statement task) (:task-type task) (:occurrence task)])</pre></td></tr><tr><td class="docs"><p>The budget evaluation for task bag element quality.</p>
</td><td class="codes"><pre class="brush: clojure">(defn measure-budget
   ;TODO revise
  [budg]
  (first budg))                                             ;higher priority means higher evaluation similar as for confidence in truth consideration</pre></td></tr><tr><td class="docs"><p>higher priority means higher evaluation similar as for confidence in truth consideration</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>Returns the bigger budget</p>
</td><td class="codes"><pre class="brush: clojure">(defn max-budget
  [budg1 budg2]                            ;the one with higher priority determines the budget
  (apply max-key measure-budget [budg1 budg2]))</pre></td></tr><tr><td class="docs"><p>The truth evaluation for task bag belief quality.</p>
</td><td class="codes"><pre class="brush: clojure">(defn measure-truth
  [task]                                    ; higher confidence means higher evaluation
  (second (:truth (project-eternalize-to @nars-time task @nars-time)))) ;prefer current events</pre></td></tr><tr><td class="docs"><p>prefer current events</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>Create an element from the </p>
</td><td class="codes"><pre class="brush: clojure">(defn make-element
  [task]
  {:id (get-task-id task) :priority (first (:budget task)) :task task})</pre></td></tr><tr><td class="docs"><p>Take the better solution of both when merging bag elements</p>
</td><td class="codes"><pre class="brush: clojure">(defn take-better-solution
  [result t1 t2]
  (let [sol1 (:solution t1)
        sol2  (:solution t2)]
    (if (or (not= nil sol1)
            (not= nil sol2)) ;project both to result time and then use the better solution for our result:
      (let [sol1-proj (project-eternalize-to (:occurrence result) sol1 @nars-time)
            sol2-proj (project-eternalize-to (:occurrence result) sol2 @nars-time)
            best-solution (apply max-key
                                 (fn [a] (second (:truth a)))
                                 (filter #(not= nil %) [sol1-proj sol2-proj]))]
        (assoc result :solution best-solution))
      result)))</pre></td></tr><tr><td class="docs"><p>Defines which task is better for deciding which one to keep.</p>
</td><td class="codes"><pre class="brush: clojure">(defn better-task
  [t1 t2]                                   ;take care here with t1 t2!! ^^
  (if (= t1 nil)                                            ;no previous bag entry exists
    t2                                                      ;so take the new one
    (if (not= nil (:truth t1))
      (take-better-solution (max-key (comp measure-truth) t1 t2) t1 t2)
      (take-better-solution (max-key (comp measure-budget :budget) t1 t2) t1 t2))))</pre></td></tr><tr><td class="docs"><p>Add the task to the tasks bag</p>
</td><td class="codes"><pre class="brush: clojure">(defn add-to-tasks
  [state task]
  (let [bag (:tasks @state)
        el (make-element task)
        [{t2 :task :as existing-el} _] (b/get-by-id bag (:id el))
        chosen-task (better-task t2 task)                   ;the second one is kept if equal so the order is important here!!
        new-budget (if existing-el
                     (max-budget (:budget task)
                                 (:budget t2))
                     (:budget task))
        new-el (make-element (assoc chosen-task :budget new-budget))
        bag' (b/add-element bag new-el)]
    (set-state! (assoc @state :tasks bag'))))</pre></td></tr><tr><td class="docs"><p>Update an existing task bag element</p>
</td><td class="codes"><pre class="brush: clojure">(defn update-task-in-tasks
  [state task old-task]
  (let [[element bag] (b/get-by-id (:tasks @state) (get-task-id old-task))]
    (when element
      (set-state! (assoc @state :tasks bag))))
  (set-state! (assoc @state :tasks (b/add-element (:tasks @state) (make-element task)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn inc-budget ;task was revised, this is further evidence for the quality of the task
  [[p d q]] ;as it seems to take part in summarizing experience instead of describing one-time phenomena
  [(t-or p 0.3) (t-or d 0.1) (t-or q 0.3)])</pre></td></tr><tr><td class="docs"><p>Revision of two tasks.</p>
</td><td class="codes"><pre class="brush: clojure">(defn revise
  [t1 t2]
  (let [revised-truth (nal.deriver.truth/revision (:truth t1) (:truth t2))
        evidence (make-evidence (:evidence t1) (:evidence t2))
        lbudget-left (if-let [budg (:lbudgets t1)] budg {})
        lbudget-right (if-let [budg (:lbudgets t2)] budg {})]
    (let [revised-task (dissoc (assoc t1 :truth revised-truth :source :derived :evidence evidence
                                 :budget (max-budget (:budget t1) (:budget t2))
                                         :lbudgets (merge lbudget-left lbudget-right))
                       :record)]
      (assoc revised-task :budget (inc-budget (:budget revised-task)) #_(derived-budget t1 revised-task)))))</pre></td></tr><tr><td class="docs"><p>The quality of an answer, which is the confidence for y/n questions,
  and the truth expectation, also taking complexity into account for what-questions</p>
</td><td class="codes"><pre class="brush: clojure">(defn answer-quality
  [question solution]
  (if solution
    (if (some #{'qu-var} (flatten (:statement question)))
      (/ (expectation (:truth solution)) (Math/sqrt (:sc solution)))
      (confidence solution))
    0))</pre></td></tr><tr><td class="docs"><p>whether the solution is better than the solution the task holds</p>
</td><td class="codes"><pre class="brush: clojure">(defn better-solution
  [solution task]
  (let [projected-solution (project-eternalize-to (:occurrence task) solution @nars-time)
        cur-solution (project-eternalize-to (:occurrence task) (:solution task) @nars-time)]
    (or (= nil cur-solution)
        (&gt;= (answer-quality task projected-solution)
            (answer-quality task cur-solution)))))</pre></td></tr><tr><td class="docs"><p>Reduction of budget due to satisfaction of goal by belief</p>
</td><td class="codes"><pre class="brush: clojure">(defn reduced-goal-budget-by-belief
  [goal belief]                     ;by belief satisfied goal
  (let [satisfaction (- 1.0 (Math/abs (- (expectation (:truth goal))
                                         (expectation (:truth belief)))))
        budget (:budget goal)
        p (first budget)
        p-new (t-and p (- 1.0 satisfaction))]
    (assoc goal :budget [p-new (second budget) (nth budget 2)])))</pre></td></tr><tr><td class="docs"><p>Reduced budget due to answer quality of a belief that answers a question.</p>
</td><td class="codes"><pre class="brush: clojure">(defn reduced-question-budget-by-belief
  [question belief]
  (let [budget (:budget question)
        p (first budget)
        p-new (t-and p (- 1.0 (answer-quality question belief)))]
    (assoc question :budget [p-new (second budget) (nth budget 2)])))</pre></td></tr><tr><td class="docs"><p>Increasing the belief budget due to its usefulness of answering the question.</p>
</td><td class="codes"><pre class="brush: clojure">(defn increased-belief-budget-by-question
  [belief question]  ;useful belief, answered a question
  (let [budget (:budget belief)
        q (nth budget 2)
        k 0.001
        ;d-new (t-or d (* k (confidence belief)))
        q-new (t-or q (* k (nth (:budget belief) 2)))]
    (assoc belief :budget [(first budget) (second budget) q-new])))                                                 ;1-confidence(solution)</pre></td></tr><tr><td class="docs"><p>1-confidence(solution)</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>Reducing the quest budget because of the answer quality of the goal that answers it.</p>
</td><td class="codes"><pre class="brush: clojure">(defn reduced-quest-budget-by-goal
  [quest goal]                     ;by goal satisfied quest
  (reduced-question-budget-by-belief quest goal))</pre></td></tr><tr><td class="docs"><p>Increasing the goal budget because it was useful in answering the quest.</p>
</td><td class="codes"><pre class="brush: clojure">(defn increased-goal-budget-by-quest
  [goal quest]                     ;useful goal, answered a quest
  (increased-belief-budget-by-question goal quest))</pre></td></tr><tr><td class="docs"><p>Increasing the belief budget because it was useful for answering a goal.</p>
</td><td class="codes"><pre class="brush: clojure">(defn increased-belief-budget-by-goal
  [belief goal]                     ;by belief satisfied goal
  (increased-belief-budget-by-question belief goal))</pre></td></tr><tr><td class="docs"><p>increased-belief-budget-by-goal</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>TODO handle in question/quest handling:
increased-goal-budget-by-quest
increased-belief-budget-by-question</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>Decrease question budget because of the answer quality.</p>

<p>decrease-quest-question-budget-by-solution:</p>
</td><td class="codes"><pre class="brush: clojure">(defn decrease-question-budget-by-solution
  [question]
  (let [budget (:budget question)
        solution (:solution question)]
    ;todo improve budget function here
    (let [new-budget [(* (- 1.0 (answer-quality question solution)) (first budget))
                      (second budget)
                      (nth budget 2)]] ;TODO dependent on solution confidence
      (assoc question :budget new-budget))))</pre></td></tr><tr><td class="docs"><p>Decrease quest budget because of the answer quality.</p>
</td><td class="codes"><pre class="brush: clojure">(defn decrease-quest-budget-by-solution
  [quest]
  (decrease-question-budget-by-solution quest))</pre></td></tr><tr><td class="docs"><p>Get the tasks in the concept.</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-tasks
  [state]
  (let [tasks (vec (for [x (:elements-map (:tasks @state))] (:task (val x))))]
    ;(println (str &quot;count: &quot;  (count (:elements-map (:tasks @state))) &quot; gt tasks: &quot; tasks))
    tasks))</pre></td></tr><tr><td class="docs"><p>Check whether the occurrence types are equal.</p>
</td><td class="codes"><pre class="brush: clojure">(defn same-occurrence-type
  [t1 t2]
  (or (and (= (:occurrence t1) :eternal) (= (:occurrence t2) :eternal))
      (and (not= (:occurrence t1) :eternal) (not= (:occurrence t2) :eternal))))</pre></td></tr><tr><td class="docs"><p>Question variables transformed to a representation core.unify can work with.</p>
</td><td class="codes"><pre class="brush: clojure">(defn qu-var-transform
  [term]
  (if (coll? term)
    (if (= (first term) 'qu-var)
      (symbol (str &quot;?&quot; (second term)))
      (apply vector (for [x term]
                      (qu-var-transform x))))
    term))</pre></td></tr><tr><td class="docs"><p>Placeholders replaced because core.unify would treat them as do not cares.</p>
</td><td class="codes"><pre class="brush: clojure">(defn placeholder-transform
  [term]
  (if (coll? term)
    (apply vector (for [x term]
                    (placeholder-transform x))))
  (if (= term '_)
    '_IMAGE_PLACEHOLDER_
    term))                                  ;TODO</pre></td></tr><tr><td class="docs"><p>TODO</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>Check that it did not unify incorrectly by assigning a dependent var to a question var.</p>
</td><td class="codes"><pre class="brush: clojure">(defn valid-answer-unifier
  [unifier]
  (not (some #{'dep-var} (flatten (vals unifier)))))</pre></td></tr><tr><td class="docs"><p>Does the solution unify with the question?</p>
</td><td class="codes"><pre class="brush: clojure">(defn question-unifies
  [question solution]
  (try (let [unifier (unify (placeholder-transform (qu-var-transform question)) (placeholder-transform solution))]
     (when (and unifier
                (valid-answer-unifier unifier))
       true))
       (catch Exception ex (println (str &quot;question unification issue with question &quot;
                                         question
                                         &quot;\nanswer:&quot;
                                         solution
                                         &quot;\n&quot; ex) ))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.memory-management.local-inference.question-processor" name="narjure.memory-management.local-inference.question-processor"><h1 class="project-name">narjure.memory-management.local-inference.question-processor</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.memory-management.local-inference.question-processor
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [taoensso.timbre :refer [debug info]]
    [narjure.bag :as b]
    [narjure.debug-util :refer :all]
    [narjure.control-utils :refer :all]
    [narjure.global-atoms :refer :all]
    [narjure.memory-management.local-inference.local-inference-utils :refer :all]
    [nal.deriver.truth :refer [t-or confidence frequency]]
    [nal.deriver.projection-eternalization :refer [project-eternalize-to]])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs"><p>Process a question task: Check how much its answered and add to bag.</p>
</td><td class="codes"><pre class="brush: clojure">(defn process-question
  [state question]
  (let [beliefs (filter #(and (= (:task-type %) :belief)
                              (question-unifies (:statement question) (:statement %)))
                        (get-tasks state))]
    ;filter beliefs matching concept content
    ;project to task time
    ;select best ranked
    (let [projected-belief-tuples (map (fn [a] [a (project-eternalize-to (:occurrence question) a @nars-time)]) beliefs)]
      (if (not-empty projected-belief-tuples)
        ;select best solution
        (let [[belief projected-belief] (apply max-key (fn [a] (answer-quality question (second a))) projected-belief-tuples)
              answerered-question (assoc question :solution belief)]
          (if (or (= (:solution question) nil)
                  (better-solution projected-belief
                                   question))
            ;update budget and tasks
            (let [result (decrease-question-budget-by-solution answerered-question)]
              ;Update goal also:
              (let [new-belief (increased-belief-budget-by-question projected-belief question)]
                (update-task-in-tasks state (assoc belief :budget (:budget new-belief)) belief))
              (add-to-tasks state result)                   ;its a new question
              ;if answer to user quest ouput answer
              (potential-output-answer state (get-task-id question) question (:solution result)))
            (add-to-tasks state question)        ;it was not better, we just add the question and dont replace the solution))
        ;was empty so just add
        (add-to-tasks state question)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.memory-management.local-inference.quest-processor" name="narjure.memory-management.local-inference.quest-processor"><h1 class="project-name">narjure.memory-management.local-inference.quest-processor</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.memory-management.local-inference.quest-processor
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [taoensso.timbre :refer [debug info]]
    [narjure.bag :as b]
    [narjure.debug-util :refer :all]
    [narjure.control-utils :refer :all]
    [narjure.global-atoms :refer :all]
    [narjure.memory-management.local-inference.local-inference-utils :refer :all]
    [nal.deriver.truth :refer [t-or confidence frequency]]
    [nal.deriver.projection-eternalization :refer [project-eternalize-to]])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs"><p>Process a quest task: Check how much its answered and add to bag.</p>
</td><td class="codes"><pre class="brush: clojure">(defn process-quest
  [state quest]
  (let [goals (filter #(and (= (:task-type %) :goal)
                            (question-unifies (:statement quest) (:statement %)))
                      (get-tasks state))]
    ;filter beliefs matching concept content
    ;project to task time
    ;select best ranked
    (let [projected-goal-tuples (map (fn [a] [a (project-eternalize-to (:occurrence quest) a @nars-time)]) goals)]
      (if (not-empty projected-goal-tuples)
        ;select best solution
        (let [[goal projected-goal] (apply max-key (fn [a] (answer-quality quest (second a))) projected-goal-tuples)
              answerered-quest (assoc quest :solution goal)]
          (if (or (= (:solution quest) nil)
                  (better-solution projected-goal
                                   quest))
            ;update budget and tasks
            (let [result (decrease-quest-budget-by-solution answerered-quest)]
              ;Update goal also:
              (let [new-goal (increased-goal-budget-by-quest projected-goal quest)]
                (update-task-in-tasks state (assoc goal :budget (:budget new-goal)) goal))
              (add-to-tasks state result)                   ;its a new quest
              ;if answer to user quest ouput answer
              (potential-output-answer state (get-task-id quest) quest (:solution result)))
            (add-to-tasks state quest)        ;it was not better, we just add the question and dont replace the solution))
        ;was empty so just add
        (add-to-tasks state quest)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.memory-management.task-dispatcher" name="narjure.memory-management.task-dispatcher"><h1 class="project-name">narjure.memory-management.task-dispatcher</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.memory-management.task-dispatcher
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [nal.term_utils :refer [concept-term-transform]]
    [narjure.global-atoms :refer [c-bag]]
    [narjure.memory-management.local-inference.local-inference-utils :refer [get-task-id]]
    [narjure.bag :as b]
    [taoensso.timbre :refer [debug info]]
    [narjure.debug-util :refer :all])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def aname :task-dispatcher)                                ; actor name</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def display (atom '()))                                    ; for lense output</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def search (atom ))                                      ; for lense output filtering</pre></td></tr><tr><td class="docs"><p>return true if task is event otherwise false</p>
</td><td class="codes"><pre class="brush: clojure">(defn event?
  [{:keys [occurrence]}]
  (not= occurrence :eternal))</pre></td></tr><tr><td class="docs"><p>Returns true if concept bag contains term</p>
</td><td class="codes"><pre class="brush: clojure">(defn term-exists?
  [term]
  (b/exists? @c-bag term))</pre></td></tr><tr><td class="docs"><p>If concept, or any sub concepts, do not exist post task to concept-creator,
   otherwise, dispatch task to respective concepts. Also, if task is an event
   dispatch task to event buffer actor.</p>
</td><td class="codes"><pre class="brush: clojure">(defn task-handler
  [from [_ [task-concept-id_ belief-concept-id_ task]]]
  (let [task-concept-id (concept-term-transform task-concept-id_)
        belief-concept-id (concept-term-transform belief-concept-id_)
        terms (map concept-term-transform (:terms task))]
    (if (every? term-exists? terms)
      (let [task (dissoc task :terms)]
        (when task-concept-id
          (when-let [{c-ref :ref} ((:elements-map @c-bag) task-concept-id)]
            (cast! c-ref [:link-feedback-msg [task belief-concept-id]])))
        (doseq [term terms]
          (when-let [{c-ref :ref} ((:elements-map @c-bag) term)]
            (cast! c-ref [:task-msg [task]]))))
      (cast! (whereis :concept-manager) [:create-concept-msg [task-concept-id belief-concept-id task]]))))</pre></td></tr><tr><td class="docs"><p>If concept, or any sub concepts, do not exist post task to concept-creator,
   otherwise, dispatch task to respective concepts. Also, if task is an event
   dispatch task to event buffer actor.</p>
</td><td class="codes"><pre class="brush: clojure">(defn task-from-cmanager-handler
  [from [_ [task-concept-id belief-concept-id task]]] ;interval transform already applied to task-concept-id, belief-concept-id
  (let [terms (map concept-term-transform (:terms task))]
    (let [task (dissoc task :terms)]
      (when task-concept-id
        (when-let [{c-ref :ref} ((:elements-map @c-bag) task-concept-id)]
          (cast! c-ref [:link-feedback-msg [task belief-concept-id]])))
      (doseq [term terms]
        (when (b/exists? @c-bag term)
          (when-let [{c-ref :ref} ((:elements-map @c-bag) term)]
            (cast! c-ref [:task-msg [task]])))))))</pre></td></tr><tr><td class="docs"><p>Identifies message type and selects the correct message handler.
   if there is no match it generates a log message for the unhandled message</p>
</td><td class="codes"><pre class="brush: clojure">(defn msg-handler
  [from [type :as message]]
  (debuglogger search display message)
  (case type
    :task-msg (task-handler from message)
    :task-from-cmanager-msg (task-from-cmanager-handler from message)
    (debug aname (str &quot;unhandled msg: &quot; type))))</pre></td></tr><tr><td class="docs"><p>Initialises actor:
    registers actor and sets actor state</p>
</td><td class="codes"><pre class="brush: clojure">(defn initialise
  [aname actor-ref]
  (reset! display '())
  (register! aname actor-ref)
  ; cache actor references for performance
  ;(set-state! {:concept-manager (whereis :concept-manager)}))</pre></td></tr><tr><td class="docs"><p>creates gen-server for task-dispatcher. This is used by the system supervisor</p>
</td><td class="codes"><pre class="brush: clojure">(defn task-dispatcher
  []
  (gen-server
    (reify Server
      (init [_] (initialise aname @self))
      (terminate [_ _])
      (handle-cast [_ from _ message] (msg-handler from message)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.memory-management.termlink-utils" name="narjure.memory-management.termlink-utils"><h1 class="project-name">narjure.memory-management.termlink-utils</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.memory-management.termlink-utils
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [taoensso.timbre :refer [debug info]]
    [narjure
     [global-atoms :refer :all]
     [bag :as b]
     [debug-util :refer :all]
     [control-utils :refer :all]
     [defaults :refer :all]
     [budget-functions :refer :all]]
    [narjure.memory-management
     [concept-utils :refer :all]]
    [clojure.core.unify :refer [unifier]]
    [nal.term_utils :refer [syntactic-complexity termlink-subterms]]
    [narjure.memory-management.local-inference
     [local-inference-utils :refer [get-task-id get-tasks update-task-in-tasks]]
     [belief-processor :refer [process-belief]]
     [goal-processor :refer [process-goal]]
     [quest-processor :refer [process-quest]]
     [question-processor :refer [process-question]]]
    [nal.deriver
     [truth :refer [w2c t-or t-and confidence frequency expectation revision]]
     [projection-eternalization :refer [project-eternalize-to]]]
    [clojure.set :as set])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs"><p>disallow linking to itself</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-linkable-terms
  [task]
  (filter #(not= % (:id @state)) (termlink-subterms (:statement task))))</pre></td></tr><tr><td class="docs"><p>only use links whose target concept still exists</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-existing-terms-from-links
  [links]
  (filter #(b/exists? @c-bag %) (keys links)))</pre></td></tr><tr><td class="docs"><p>This one is for absolute forgetting of links: Remove termlinks whose concepts were forgot,
  remove worst termlinks if above max termlink count.</p>
</td><td class="codes"><pre class="brush: clojure">(defn forget-termlinks-absolute
  []
  (doseq [[tl _] (:termlinks @state)]
    (when (not (b/exists? @c-bag tl))
      (set-state! (assoc @state :termlinks (dissoc (:termlinks @state) tl)))))
  (while (&gt; (count (:termlinks @state)) concept-max-termlinks)
    (let [worst (apply min-key (comp expectation second) (:termlinks @state))]
      (set-state! (assoc @state :termlinks (dissoc (:termlinks @state) (first worst)))))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn forget-termlinks-relative []
  &quot;Forget termlinks relative.&quot;
  (set-state! (assoc @state :termlinks (apply merge (for [[tl [f c]] (:termlinks @state)]
                                                      {tl (revision [f c] [0.0 0.001])})))))</pre></td></tr><tr><td class="docs"><p>Adds a termlink with term tl and strength strength.</p>
</td><td class="codes"><pre class="brush: clojure">(defn add-termlink
  [tl strength]
  (set-state! (assoc @state :termlinks (assoc (:termlinks @state)
                                         tl strength)))
  ;(forget-termlinks))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn calc-link-strength
  ([tl]
    (calc-link-strength tl [0.5 0.01]))
  ([tl old-strength]
  old-strength
    #_(let [prio-me (concept-priority (:id @state))
        prio-other (concept-priority tl)
        evidence-mul 0.5
        association (t-and prio-me prio-other)
        disassocation (t-and prio-me (- 1.0 prio-other))]
    (revision [0.0 (* evidence-mul disassocation)]
              (revision old-strength [1.0 (* evidence-mul association)])))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn update-termlink [tl]                                  ;term
  (let [old-strength ((:termlinks @state) tl)]
    (add-termlink tl (calc-link-strength tl (if old-strength old-strength [0.5 0.0])))
    (forget-termlinks-absolute)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn use-stronger [t1 t2]
  (let [all-keys (set/union (map first t1) (map first t2))]
    (apply merge (for [k all-keys]
                 (let [str1 (when t1 (t1 k))
                       str2 (when t2 (t2 k))
                       st1 (if str1 str1 [0.0 0.0])
                       st2 (if str2 str2 [0.0 0.0])]
                   (if (&gt; (first st1) (first st2))
                     {k st1}
                     {k st2}))))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn refresh-termlinks [task]
  &quot;Create new potential termlinks to other terms modulated by the concept priority they link to.&quot;
  ; :termlinks {term [budget]}
  (let [concept-prio (fn [z] (let [prio (concept-priority z)]
                               (if prio
                                 prio
                                 0.0)))
        newtermlinks (use-stronger (apply merge
                                   (for [tl (get-linkable-terms task)] ;prefer existing termlinks strengths
                                     {tl (calc-link-strength tl) #_[(* (first termlink-default-budget)
                                                                                                         (concept-prio tl)) (second termlink-default-budget)]}))
                            (:termlinks @state))
        valid-links (select-keys newtermlinks (get-existing-terms-from-links newtermlinks))];only these keys which exist in concept bag
    (set-state! (merge @state {:termlinks valid-links}))))</pre></td></tr><tr><td class="docs"><p>https://clojuredocs.org/clojure.core/when-let</p>
</td><td class="codes"><pre class="brush: clojure">(defmacro when-let*
  ([bindings &amp; body]
   (if (seq bindings)
     `(when-let [~(first bindings) ~(second bindings)]
        (when-let* ~(drop 2 bindings) ~@body))
     `(do ~@body))))</pre></td></tr><tr><td class="docs"><p>Link growth by contextual relevance of the inference and the result, as well as usefulness of the result.</p>
</td><td class="codes"><pre class="brush: clojure">(defn link-feedback-handler
  [from [_ [derived-task belief-concept-id]]]                       ;this one uses the usual priority durability semantics
  (try
    ;TRADITIONAL BUDGET INFERENCE (BLINK PART)
    (let [truth-quality (if (:truth derived-task)
                 (truth-to-quality (:truth derived-task))
                 (w2c 1.0))
          truth-quality-to-confidence (* truth-quality 1.0)
          [f c] ((:termlinks @state) belief-concept-id)
          premise-task-id (first (:parent-statement derived-task))]
      (when (and f c (:truth derived-task)) ;just revise by using the truth value directly
        (add-termlink belief-concept-id (revision [1.0 truth-quality-to-confidence] [f c]))
        (forget-termlinks-absolute)
        (when-let* [[element _] (b/get-by-id (:tasks @state) premise-task-id)
                   elem-task (:task element)
                    lbudgets (if-let [buds (:lbudgets elem-task)] buds {})
                    lbudget (if-let [bud (belief-concept-id lbudgets)] bud [0.5 0.0])
                    lbudget* (revision [1.0 truth-quality-to-confidence] lbudget)
                    lbudgets* (assoc lbudgets belief-concept-id lbudget*)
                    task* (assoc elem-task :lbudgets lbudgets*)]
                   (update-task-in-tasks state task* elem-task))))
    (catch Exception e () #_(println &quot;fail&quot;))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn not-outdated-record-entry [[id time]]
  (&lt; (- @nars-time time) 25))</pre></td></tr><tr><td class="docs"><p>Get the link endpoints, namely the concepts which the concept links to: their id as well as priority.</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-termlink-endpoints
  [record link-budgets]
  (let [initbag (b/default-bag concept-max-termlinks)
        get-link-budget-exp (fn [k] (if (and link-budgets (k link-budgets))
                                  (expectation (k link-budgets))
                                  0.0))
        individual-budget-weight 1.0]
    (try
      (reduce (fn [a b] (b/add-element a b)) initbag (for [[k v] (filter (fn [[k _]] (or (nil? record)
                                                                                         (not (some (fn [[id time]]
                                                                                                      (and
                                                                                                        (not-outdated-record-entry [id time])
                                                                                                        (= id k)))
                                                                                                    record))))
                                                                         (:termlinks @state))]
                                                      {:priority (+    (expectation v)
                                                                       (* individual-budget-weight (get-link-budget-exp k))
                                                                   (:priority (first (b/get-by-id @c-bag k))))
                                                       :id       k}))
      (catch Exception e (print &quot;&quot;)
                         ;(println (str &quot;error in get-termlink-endpoints: &quot; e)))))</pre></td></tr><tr><td class="docs"><p>Select the termlink probabilistically, taking link strength and target priorities into account.</p>
</td><td class="codes"><pre class="brush: clojure">(defn select-termlink-ref
  [record link-budgets]
  ;now search through termlinks, get the endpoint concepts, and form a bag of them
  (let [initbag (b/default-bag concept-max-termlinks)
        resbag (get-termlink-endpoints record link-budgets)]
    ;now select an element from this bag
    (if (and resbag (pos? (b/count-elements resbag)))
      (let [[beliefconcept _] (b/get-by-index resbag (selection-fn (b/count-elements resbag)))]
        #_(forget-termlink (:id beliefconcept))               ;apply forgetting for termlinks only on selection
        [(:id beliefconcept) (get-ref-from-term (:id beliefconcept))])
      nil)))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.narsese" name="narjure.narsese"><h1 class="project-name">narjure.narsese</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.narsese
  (:require [instaparse.core :as i]
            [clojure.java.io :as io]
            [narjure.defaults :refer :all]
            [nal.term_utils :refer :all]
            [clojure.string :as str]
            [nal.deriver.normalization :refer [sort-commutative]]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def bnf-file &quot;narsese.bnf&quot;)</pre></td></tr><tr><td class="docs"><p>Loads narsese.bnf into instaparse</p>
</td><td class="codes"><pre class="brush: clojure">(def parser
  (i/parser (io/resource bnf-file) :auto-whitespace :standard))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def copulas
  {&quot;--&gt;&quot;  '--&gt;
   &quot;&lt;-&gt;&quot;  '&lt;-&gt;
   &quot;{--&quot;  'instance
   &quot;--]&quot;  'property
   &quot;{-]&quot;  'instance-property
   &quot;==&gt;&quot;  '==&gt;
   &quot;=/&gt;&quot;  'pred-impl
   &quot;=|&gt;&quot;  '=|&gt;
   &quot;=\\&gt;&quot; 'retro-impl
   &quot;&lt;=&gt;&quot;  '&lt;=&gt;
   &quot;&lt;/&gt;&quot;  '&lt;/&gt;
   &quot;&lt;|&gt;&quot;  '&lt;|&gt;})</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def compound-terms
  {&quot;{&quot;  'ext-set
   &quot;[&quot;  'int-set
   &quot;&amp;&quot;  'ext-inter
   &quot;|&quot;  '|
   &quot;-&quot;  '-
   &quot;~&quot;  'int-dif
   &quot;*&quot;  '*
   &quot;(&quot;  '*
   &quot;/&quot;  'ext-image
   &quot;\\&quot; 'int-image
   &quot;--&quot; '--
   &quot;||&quot; '||
   &quot;&amp;&amp;&quot; 'conj
   &quot;&amp;/&quot; 'seq-conj
   &quot;&amp;|&quot; '&amp;|})</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn get-compound-term [[_ operator-srt]]
  (compound-terms operator-srt))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def actions {&quot;.&quot; :belief
              &quot;?&quot; :question
              &quot;@&quot; :quest
              &quot;!&quot; :goal})</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def ^:dynamic *action* (atom nil))
(def ^:dynamic *lvars* (atom []))
(def ^:dynamic *truth* (atom []))
(def ^:dynamic *budget* (atom []))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn keep-cat [fun col]
  (into [] (comp (mapcat fun) (filter (complement nil?))) col))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn dispatcher [data]
  (if (string? data) :default (first data)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmulti element dispatcher)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn get-copula [[_ [_ cop-symbol]]]
  (copulas cop-symbol))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod element :sentence [[_ &amp; data]]
  (let [filtered (group-by string? data)]
    (reset! *action* (actions (first (filtered true))))
    (let [cols (filtered false)
          last-el (last cols)]
      (when (= :truth (first last-el))
        (element last-el))
      (element (first cols)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod element :statement [[_ &amp; data]]
  (if-let [copula (get-copula data)]
    `[~copula ~@(keep-cat element data)]
    (keep-cat element data)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod element :task [[_ &amp; data]]
  `[~@(keep-cat element data)])</pre></td></tr><tr><td class="docs"><p>looks strange but it is because of special syntax for negation --bird.</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-comp-operator [second-el data]
  (let [first-el-type (get-in (vec data) [0 0])]
    (if (some #{(first second-el)} [:op-negation :op-int-set
                                    :op-ext-set :op-product])
      second-el
      ((if (= :term first-el-type) second first) data))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod element :compound-term [[_ second-el &amp; data]]
  (let [comp-operator (get-comp-operator second-el data)]
    `[~(get-compound-term comp-operator)
      ~@(keep-cat element (remove string? data))]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def var-prefixes '{&quot;#&quot; dep-var &quot;?&quot; qu-var &quot;$&quot; ind-var})
(defmethod element :variable [[_ type [_ v]]]
  (let [front (var-prefixes type)
        v [front (symbol v)]]
    (swap! *lvars* conj v)
    v))                                                     ;let v (symbol (str (var-prefixes type) v))</pre></td></tr><tr><td class="docs"><p>let v (symbol (str (var-prefixes type) v))</p>
</td><td class="codes"></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod element :word [[_ word]] (symbol word))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod element :truth
  [[_ &amp; data]]
  (mapv element data))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod element :budget
  [[_ &amp; data]]
  `[[~@(mapv element data)]])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmacro double-element [n a]
  `(defmethod element ~n [[t# d#]]
     (let [d# (Double/parseDouble d#)]
       (swap! ~a conj d#) d#)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(double-element :frequency *truth*)
(double-element :confidence *truth*)
(double-element :priority *budget*)
(double-element :durability *budget*)
(double-element :quality *budget*)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod element :task [[_ &amp; data]]
  (when (= :budget (ffirst data))
    (element (first data)))
  (element (last data)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod element :term [[_ &amp; data]]
  (when (seq? data)
    (keep element data)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defmethod element :default [_])</pre></td></tr><tr><td class="docs"><p>Fetch terms from task.</p>

<p>TODO check for variables in statemnts, ignore subterm if it contains variable</p>
</td><td class="codes"><pre class="brush: clojure">(defn terms
  [statement]
  (into #{statement} (rest statement)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn check-truth-value [v]
  (concat v (nthrest truth-value (count v))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn check-budget [v act]
  (let [budget (budgets act)]
    (concat v (nthrest budget (count v)))))</pre></td></tr><tr><td class="docs"><p>Parses a Narsese string into task ready for inference</p>
</td><td class="codes"><pre class="brush: clojure">(defn parse
  [narsese-str]
  (let [data (parser narsese-str)]
    (if-not (i/failure? data)
      (binding [*action* (atom nil)
                *lvars* (atom [])
                *truth* (atom [])
                *budget* (atom [])]
        (let [statement (element data)
              act @*action*]
          {:task-type act
           :lvars     @*lvars*
           :truth     (check-truth-value @*truth*)
           :budget    (check-budget @*budget* act)
           :statement statement
           ;:terms     (terms statement)  ; this is now done in task-creator and uses termlink-subterms
           }))
      data)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn parse2 [stmt-with-potential-comment]
  &quot;workaround in order to have (&amp;&amp;,a) as [conj a] rather than [[conj a]],
  also in order to support :|: as 0 occurring versus :eternal
  and also in order to support recognizing i50 as [interval 50], op_test as ^test
  so everything needed to workaround the parser issues.
  Also apply sentence reduction here, as also done for derivations.&quot;            ;TODO fix paser accordingly when there is time!
  (let [stmt (clojure.string/replace (first (str/split stmt-with-potential-comment #&quot;//&quot;)) &quot;^&quot; &quot;op_&quot;) ;get rid of comments
        parser-workaround (fn [prem, stmt]
                            (if (and (vector? stmt)
                                     (= (count stmt) 1))
                              (assoc prem :statement (first stmt))
                              (assoc prem :statement stmt)))
        time (if (.contains stmt &quot;:|:&quot;)
               0
               (if (and (.contains stmt &quot;:|&quot;)
                        (.contains stmt &quot;|:&quot;))
                 (read-string (first (str/split (second (str/split stmt #&quot;\:\|&quot;)) #&quot;\|\:&quot;)))
                 :eternal))
        parsedstmt (assoc (parse (str (first (str/split stmt #&quot;\:\|&quot;))
                                      (second (str/split stmt #&quot;\|\:&quot;)))) :occurrence time)]
    (let [parsed (interval-reduction (parser-workaround parsedstmt (parse-intervals (:statement parsedstmt))))]
      (no-truth-for-questions-and-quests (assoc parsed :statement (sort-commutative (:statement parsed)))))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.perception-action.derived-load-reducer" name="narjure.perception-action.derived-load-reducer"><h1 class="project-name">narjure.perception-action.derived-load-reducer</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.perception-action.derived-load-reducer
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [taoensso.timbre :refer [debug info]]
    [narjure.bag :as b]
    [narjure.control-utils :refer :all]
    [narjure.defaults :refer :all]
    [narjure.global-atoms :refer [nars-time]]
    [narjure.memory-management.local-inference.local-inference-utils :refer [get-task-id]]
    [narjure.debug-util :refer :all])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def aname :derived-load-reducer)                           ; actor name</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def display (atom '()))                                    ; for lense output</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def search (atom ))                                      ; for lense output filtering</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def d-bag (atom (b/default-bag max-derived-sentences)))      ; task bag</pre></td></tr><tr><td class="docs"><p>select n sentences from input bag and post to :task-creator</p>
</td><td class="codes"><pre class="brush: clojure">(defn system-time-tick-handler
  []
  (doseq [n (range (min max-derived-selections (b/count-elements @d-bag)))]
    (let [[element d-bag'] (b/get-by-index @d-bag (selection-fn (b/count-elements @d-bag)))
          msg [:derived-sentence-msg [(:task-concept-id element) (:belief-concept-id element) (:task element)]]
          task-creator (whereis :task-creator)]
      (reset! d-bag d-bag')
      (cast! task-creator msg)
      (debuglogger search display [:forward msg]))))</pre></td></tr><tr><td class="docs"><p>adds sentence to input-bag and selects n senetences on system-time-tick</p>
</td><td class="codes"><pre class="brush: clojure">(defn derived-sentence-handler
  [from [msg [task-concept-id belief-concept-id sentence]]]
  (let [elem {:id (get-task-id sentence) :priority (first (:budget sentence)) :task sentence
              :task-concept-id task-concept-id
              :belief-concept-id belief-concept-id}]
    (debuglogger search display [:add elem])
    (swap! d-bag b/add-element elem)))</pre></td></tr><tr><td class="docs"><p>add task-creator reference to state</p>
</td><td class="codes"><pre class="brush: clojure">(defn register-task-creator-handler
  [from]
  (set-state! {:task-creator from}))</pre></td></tr><tr><td class="docs"><p>Identifies message type and selects the correct message handler.
   if there is no match it generates a log message for the unhandled message </p>
</td><td class="codes"><pre class="brush: clojure">(defn msg-handler
  [from [type :as message]]
  ;(debuglogger search display message)
  (case type
    :derived-sentence-msg (derived-sentence-handler from message)
    :system-time-tick-msg (system-time-tick-handler)
    :register-task-creator-msg (register-task-creator-handler from)
    (debug aname (str &quot;unhandled msg: &quot; type))))</pre></td></tr><tr><td class="docs"><p>Initialises actor:
      registers actor and sets actor state</p>
</td><td class="codes"><pre class="brush: clojure">(defn initialise
  [aname actor-ref]
  (reset! display '())
  (register! aname actor-ref)
  (reset! d-bag (b/default-bag max-derived-sentences))
  (set-state! {:last-forgotten 0}))</pre></td></tr><tr><td class="docs"><p>creates gen-server for derived-load-reducer. This is used by the system supervisor</p>
</td><td class="codes"><pre class="brush: clojure">(defn derived-load-reducer
  []
  (gen-server
    (reify Server
      (init [_] (initialise aname @self))
      (terminate [_ _])
      (handle-cast [_ from _ message] (msg-handler from message)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.perception-action.operator-executor" name="narjure.perception-action.operator-executor"><h1 class="project-name">narjure.perception-action.operator-executor</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.perception-action.operator-executor
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [taoensso.timbre :refer [debug info]]
    [narjure.debug-util :refer :all]
    [narjure.defaults :refer [budgets]]
    [narjure.global-atoms :refer :all])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def aname :operator-executor)                              ; actor name</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def display (atom '()))                                    ; for lense output</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def search (atom ))                                      ; for lense output filtering</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def registered-operator-functions (atom {}))</pre></td></tr><tr><td class="docs"><p>Processes an :operator-execution-msg:
    executes operation with optionally supplied parameters
    if feedback msg required posts :sentence-msg to task creator</p>
</td><td class="codes"><pre class="brush: clojure">(defn operator-execution-handler
  [from [msg operationgoal]]
  (let [feedback (assoc operationgoal :task-type :belief
                                      :occurrence 0
                                      :source :input
                                      :budget (budgets :belief))
        operation (:statement operationgoal)
        arguments (if (coll? operation) (rest (second operation)) [])
        operator (if (coll? operation) (nth operation 2) operation)]
    (try (let [func (@registered-operator-functions operator)]
           (if (not= nil func)
             (let [success (func arguments operationgoal)]
               (output-task :execution operationgoal)
               (if success          ;when there is an operator function, give positive/negative feedback based on success
                 (do
                   (cast! (whereis :task-creator) [:sentence-msg feedback])
                   #_(when (coll? success)                  ;TODO collides with operation task idea
                       (doseq [custom-feedback success] ;also allowing custom feedback tasks
                         (cast! (whereis :task-creator) [:sentence-msg custom-feedback]))))
                 #_(cast! (whereis :task-creator) [:sentence-msg (assoc feedback :truth
                                                                               [(- 1.0 (first (:truth feedback)))
                                                                                (second (:truth feedback))])])))
             (do ;if no function is registered, just enter the feedback, eliminates the issue that we need to register ops just to use them in examples
               (output-task :execution operationgoal)
               (cast! (whereis :task-creator) [:sentence-msg feedback]))))
         (catch Exception e (debuglogger search display (str &quot;operator execution error &quot; (.toString e)))))
    (output-task :execution operationgoal)))</pre></td></tr><tr><td class="docs"><p>Identifies message type and selects the correct message handler.
   if there is no match it generates a log message for the unhandled message </p>
</td><td class="codes"><pre class="brush: clojure">(defn msg-handler
  [from [type :as message]]
  (debuglogger search display message)
  (case type
    :operator-execution-msg (operator-execution-handler from message)
    (debug aname (str &quot;unhandled msg: &quot; type))))</pre></td></tr><tr><td class="docs"><p>Initialises actor:
      registers actor and sets actor state</p>
</td><td class="codes"><pre class="brush: clojure">(defn initialise
  [aname actor-ref]
  (reset! display '())
  (register! aname actor-ref)
  ; cache task-creator reference for performance
  ; (set-state! {:task-creator (whereis :task-creator)}))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn operator-executor []
  &quot;creates gen-server for operator-executor. This is used by the system supervisor&quot;
  (gen-server
    (reify Server
      (init [_] (initialise aname @self))
      (terminate [_ _])
      (handle-cast [_ from _ message] (msg-handler from message)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.perception-action.sentence-parser" name="narjure.perception-action.sentence-parser"><h1 class="project-name">narjure.perception-action.sentence-parser</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.perception-action.sentence-parser
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [narjure.narsese :refer [parse2]]
    [taoensso.timbre :refer [debug info]]
    [narjure.debug-util :refer :all])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def aname :sentence-parser)                                ; actor name</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def display (atom '()))                                    ; for lense output</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def search (atom ))                                      ; for lense output filtering</pre></td></tr><tr><td class="docs"><p>Parses a narsese string and posts a :sentence-msg to input-load-reducer</p>
</td><td class="codes"><pre class="brush: clojure">(defn narsese-string-handler
  [from [msg string]]
  (try (let [sentence (parse2 string)]
         (cast! (whereis :task-creator) [:sentence-msg sentence]))
       (catch Exception e (debuglogger search display (str &quot;parsing error &quot; (.toString e))))))</pre></td></tr><tr><td class="docs"><p>Identifies message type and selects the correct message handler.
   if there is no match it generates a log message for the unhandled message </p>
</td><td class="codes"><pre class="brush: clojure">(defn msg-handler
  [from [type :as message]]
  (debuglogger search display message)
  (case type
    :narsese-string-msg (narsese-string-handler from message)
    (debug aname (str &quot;unhandled msg: &quot; type))))</pre></td></tr><tr><td class="docs"><p>Initialises actor:
      registers actor and sets actor state</p>
</td><td class="codes"><pre class="brush: clojure">(defn initialise
  [aname actor-ref]
  (reset! display '())
  (register! aname actor-ref))</pre></td></tr><tr><td class="docs"><p>creates gen-server for sentence-parser. This is used by the system supervisor</p>
</td><td class="codes"><pre class="brush: clojure">(defn sentence-parser
  []
  (gen-server
    (reify Server
      (init [_] (initialise aname @self))
      (terminate [_ _])
      (handle-cast [_ from _ message] (msg-handler from message)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.perception-action.task-creator" name="narjure.perception-action.task-creator"><h1 class="project-name">narjure.perception-action.task-creator</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.perception-action.task-creator
  (:require
    [co.paralleluniverse.pulsar
     [core :refer :all]
     [actors :refer :all]]
    [taoensso.timbre :refer [debug info]]
    [clojure.set :as set]
    [narjure
     [global-atoms :refer :all]
     [defaults :refer :all]
     [debug-util :refer :all]
     [bag :as b]
     [control-utils :refer :all]]
    [nal.term_utils :refer :all]
    [nal.deriver.projection-eternalization :refer [eternalize]])
  (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def aname :task-creator)                                   ; actor name</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def display (atom '()))                                    ; for lense output</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def search (atom ))                                      ; for lense output filtering</pre></td></tr><tr><td class="docs"><p>inc :time value in global atom for each system-time-tick-msg</p>
</td><td class="codes"><pre class="brush: clojure">(defn system-time-tick-handler
  []
  (swap! nars-time inc))</pre></td></tr><tr><td class="docs"><p>inc :nars-id in global atom after each use</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-id
  []
  (swap! nars-id inc))</pre></td></tr><tr><td class="docs"><p>create a new task with the provided sentence and default values
   convert tense to occurrence time if applicable</p>
</td><td class="codes"><pre class="brush: clojure">(defn create-new-task
  [sentence syntactic-complexity]
  (let [occurrence (:occurrence sentence)
        toc (case occurrence
              :eternal :eternal
              (+ occurrence @nars-time))
        content (:statement sentence)
        task-type (:task-type sentence)]
    {:truth (:truth sentence)
     ;:desire (:desire sentence)
     :budget (:budget sentence)
     :occurrence toc
     :source :input
     :evidence (list (get-id))
     :sc syntactic-complexity
     :terms (termlink-subterms content)
     :solution nil
     :task-type task-type
     :statement content}))</pre></td></tr><tr><td class="docs"><p>Create an eternal task from a non-eternal task</p>
</td><td class="codes"><pre class="brush: clojure">(defn create-eternal-task
  [task]
  (eternalize task))</pre></td></tr><tr><td class="docs"><p>Create a derived task with the provided sentence, budget and occurence time
   and default values for the remaining parameters</p>
</td><td class="codes"><pre class="brush: clojure">(defn create-derived-task
  [sentence]
  (let [content (:statement sentence)]
    {:truth      (:truth sentence)
     :budget     (:budget sentence)
     :occurrence (:occurrence sentence)
     :source     :derived
     :evidence   (:evidence sentence)
     :sc         (:sc sentence)
     :terms      (termlink-subterms content)
     :solution   nil
     :task-type  (:task-type sentence)
     :statement  content
     :parent-statement (:parent-statement sentence)}))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn budgetify [task])</pre></td></tr><tr><td class="docs"><p>tests whether the passed task sentence is an event</p>
</td><td class="codes"><pre class="brush: clojure">(defn event?
  [sentence]
  (not= :eternal (:occurrence sentence)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def lastevent (atom nil))</pre></td></tr><tr><td class="docs"><p>Processes a :sentence-msg and generates a task, and an eternal task
   if the sentence is an event, and posts to task-dispatcher.</p>
</td><td class="codes"><pre class="brush: clojure">(defn sentence-handler
  [from [_ sentence]]
  (let [synt-complexity (syntactic-complexity (:statement sentence))]
    (when true #_(&lt; syntactic-complexity max-term-complexity)
      (reset! max-term-complexity (max @max-term-complexity   ;adapt max. term complexity in respect to examples for now
                                      (+ term-complexity-offset
                                         synt-complexity)))
      (let [new-task (create-new-task
                       sentence
                       synt-complexity)
            task-dispatcher (whereis :task-dispatcher)]
        (cast! task-dispatcher [:task-msg [nil nil new-task]])
        (output-task :input new-task)
        (when (event? sentence)
          (when (and @lastevent
                     (= (:task-type new-task) :belief)
                     (&gt; (first (:truth new-task)) 0.5))
            (cast! (whereis :inference-request-router) [:do-inference-msg [nil nil new-task @lastevent]]))
          (when (and (belief? new-task)
                     (not (operation? (:statement new-task)))
                     (&gt; (first (:truth new-task)) 0.5))
            (reset! lastevent new-task))
          (cast! task-dispatcher [:task-msg [nil nil (create-eternal-task new-task)]]))))))</pre></td></tr><tr><td class="docs"><p>processes a :derived-sentence-msg and posts to task-dispatcher</p>
</td><td class="codes"><pre class="brush: clojure">(defn derived-sentence-handler
  [from [msg [task-concept-id belief-concept-id sentence]]]
  (let [derived-task (create-derived-task sentence)
        task-dispatcher (whereis :task-dispatcher)]
    (cast! task-dispatcher [:task-msg [task-concept-id belief-concept-id derived-task]])
    ; display task in output window
    (output-task :derived derived-task)
    (when (event? sentence)
      (cast! task-dispatcher [:task-msg [task-concept-id belief-concept-id (create-eternal-task derived-task)]]))))</pre></td></tr><tr><td class="docs"><p>Identifies message type and selects the correct message handler.
   if there is no match it generates a log message for the unhandled message </p>
</td><td class="codes"><pre class="brush: clojure">(defn msg-handler
  [from [type :as message]]
  ; don't output :system-time-tick-msg's to logger
  (when (not= type :system-time-tick-msg) (debuglogger search display message))
  (case type
    :sentence-msg (sentence-handler from message)
    :derived-sentence-msg (derived-sentence-handler from message)
    :system-time-tick-msg (system-time-tick-handler)
    ; unhandled case - report to debug logger (console by default)
    (debug aname (str &quot;unhandled msg: &quot; type))))</pre></td></tr><tr><td class="docs"><p>Initialises actor:
      registers actor and sets actor state</p>
</td><td class="codes"><pre class="brush: clojure">(defn initialise
  [aname actor-ref]
  (reset! display '())
  (register! aname actor-ref)
  ; caches task-dispatcher reference for performance
  ;(set-state! {:task-dispatcher (whereis :task-dispatcher)})
  ;(cast! (whereis :derived-load-reducer) :register-task-creator-msg []))</pre></td></tr><tr><td class="docs"><p>creates gen-server for task-creator. This is used by the system supervisor</p>
</td><td class="codes"><pre class="brush: clojure">(defn task-creator
  []
  (gen-server
    (reify Server
      (init [_] (initialise aname @self))
      (terminate [_ _])
      (handle-cast [_ from _ message] (msg-handler from message)))))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.projection-utils" name="narjure.projection-utils"><h1 class="project-name">narjure.projection-utils</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.projection-utils
  (:require
    [nal.deriver
     [projection-eternalization :refer [project-eternalize-to]]]
    [narjure
     [global-atoms :refer :all]]))</pre></td></tr><tr><td class="docs"><p>Return the element of maximum statement confidence when projected to current moment.</p>
</td><td class="codes"><pre class="brush: clojure">(defn max-statement-confidence-projected-to-now
  [state task-type event]
  (let [fil (filter (fn [z] (and (= (:task-type (:task (second z))) task-type)
                                 (or (not event)
                                     (not= (:occurrence (:task (second z))) :eternal))
                                 (= (:statement (:task (second z))) (:id state))))
                    (:elements-map (:tasks state)))]
    (if (not= fil [])
      (project-eternalize-to @nars-time
                             (:task (second (apply max-key
                                                   (fn [y]
                                                     (second (:truth
                                                               (project-eternalize-to
                                                                 @nars-time
                                                                 (:task (second y))
                                                                 @nars-time))))
                                                   fil)))
                             @nars-time)
      nil)))</pre></td></tr><tr><td class="docs"><p>Confidence of a task.</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-conf
  [task]
  (second (:truth task)))</pre></td></tr><tr><td class="docs"><p>returns the task with highest projected conf
   or the first task if task t2 is nil</p>
</td><td class="codes"><pre class="brush: clojure">(defn max-statement-confidence-projected-to-now2
  [t1 t2]
  (if t2
    (let [now @nars-time
          f project-eternalize-to]
      (f now
         (max-key
           (fn [y] (get-conf (f now y now)))
           t1 t2)
         now))
    t1))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.repl" name="narjure.repl"><h1 class="project-name">narjure.repl</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.repl
  (:require [clojure.string :as s]
            [narjure.narsese :refer [parse]]
            [instaparse.core :as i]
            [nal.core :as c]
            [clojure.core.logic :as l]
            [clojure.string :refer [trim]]
            [clojure.pprint :as p]
            [clojure.tools.nrepl.middleware :refer [set-descriptor!]]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defonce narsese-repl-mode (atom false))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn start-narsese-repl! []
  (reset! narsese-repl-mode true)
  (println &quot;Narsese repl was started.&quot;))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn stop-narsese-repl! []
  (reset! narsese-repl-mode false)
  (println &quot;Narsese repl was stopped.&quot;))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defonce db (atom {}))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn clear-db! [] (reset! db {}))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn collect!
  [{:keys [statement truth] :as task}]
  #_(swap! db cycle/task-&gt;buffer task)
  [statement truth])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn- parse-int [s]
  (try (Integer/parseInt s) (catch Exception _)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn- wrap-code [code]
  (str &quot;(narjure.repl/handle-narsese \ code &quot;\&quot;)&quot;))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn run [n]
  #_(swap! db cycle/do-cycles n)
  #_(cycle/print-results! @db)
  (swap! db dissoc :forward-inf-results :local-inf-results :answers)
  nil)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn- get-result [code]
  (let [result (parse code)]
    (if (and (not (i/failure? result)))
      (collect! result)
      result)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn handle-narsese [code]
  (let [n (parse-int (trim code))]
    (cond
      (integer? n) (do (run n) nil)
      (= &quot;stop!&quot; (trim code)) (stop-narsese-repl!)
      (= \* (first code)) (do (clear-db!) nil)
      (= \/ (first code)) 
      :default (get-result code))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn narsese-handler [handler]
  (fn [args &amp; tail]
    (apply handler (if @narsese-repl-mode
                     [(update args :code wrap-code)]
                     (cons args tail)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(set-descriptor! #'narsese-handler
                 {:expects #{&quot;eval&quot;}
                  :handles {&quot;stdin&quot;
                            {:doc      &quot;Parses Narsese&quot;
                             :requires #{&quot;code&quot; &quot;Code.&quot;}}}})</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.runtime-utils" name="narjure.runtime-utils"><h1 class="project-name">narjure.runtime-utils</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.runtime-utils
     (:require
       [co.paralleluniverse.pulsar
        [core :refer :all]
        [actors :refer :all]]
       [narjure.narsese :refer [parse2]]
       [nal.deriver.truth :refer [expectation]]
       [narjure.global-atoms :refer [lense-termlinks lense-taskbags nars-time]])
     (:refer-clojure :exclude [promise await]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn get-bag-atom [atom]
  atom)</pre></td></tr><tr><td class="docs"><p>How many concepts are there?</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-concept-count
  []
  (let [bag (get-bag-atom narjure.global-atoms/c-bag)]
    (narjure.bag/count-elements @bag)))</pre></td></tr><tr><td class="docs"><p>Get the lines of a text file.</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-lines
  [file]
  (clojure.string/split-lines (slurp file)))</pre></td></tr><tr><td class="docs"><p>Loading a NAL file into the system</p>
</td><td class="codes"><pre class="brush: clojure">(defn load-NAL-file
  [file]
  (println &quot;loading file (with delay between inputs) ...&quot;)
  (doseq [narsese-str (get-lines file)]
    (println (str narsese-str))
    (cast! (whereis :sentence-parser) [:narsese-string-msg narsese-str])
    (Thread/sleep 1000))
  (println &quot;file loaded.&quot;))</pre></td></tr><tr><td class="docs"><p>For parser performance test.</p>
</td><td class="codes"><pre class="brush: clojure">(defn test-parser
  [n]
  (doseq [i (range n)]
    (parse2 &quot;&lt;(*,{SELF}) --&gt; op_down&gt;!&quot;)))</pre></td></tr><tr><td class="docs"><p>Parser performance test.</p>
</td><td class="codes"><pre class="brush: clojure">(defn test
  [n]
  (time
    (test-parser n)))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#narjure.sensorimotor" name="narjure.sensorimotor"><h1 class="project-name">narjure.sensorimotor</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns narjure.sensorimotor
  (:require [narjure.perception-action.operator-executor :refer [registered-operator-functions]]
            [co.paralleluniverse.pulsar.actors :refer [whereis cast!]]
            [narjure.global-atoms :refer [answer-handlers]]))</pre></td></tr><tr><td class="docs"><p>Register an operation by providing a callback function.</p>
</td><td class="codes"><pre class="brush: clojure">(defn nars-register-operation
  [k f]
  (reset! registered-operator-functions (assoc @registered-operator-functions k f)))</pre></td></tr><tr><td class="docs"><p>Register an answer handler by providing a callback function.</p>
</td><td class="codes"><pre class="brush: clojure">(defn nars-register-answer-handler
  [f]
  (reset! answer-handlers (concat @answer-handlers [f])))</pre></td></tr><tr><td class="docs"><p>Input Narsese into the system.</p>
</td><td class="codes"><pre class="brush: clojure">(defn nars-input-narsese
  [str]
  (cast! (whereis :sentence-parser) [:narsese-string-msg str]))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#gui.actors" name="gui.actors"><h1 class="project-name">gui.actors</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns gui.actors
  (:require [seesaw.core :refer :all]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def actor-level-width 175)
(def actor-level-height 100)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def concept-color [200 255 255])
(def derived-task-color [200 200 255])
(def task-color [255 255 200])
(def util-color [200 255 200])
(def gui-color [240 240 255])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def nodes [{:name :concept-manager :px 400 :py 150 :backcolor task-color}
            {:name :concepts :px -100 :py 150 :backcolor concept-color}
            {:name :task-dispatcher :px 400 :py 0 :backcolor task-color}
            {:name :input :px 400 :py -400 :displaysize 10.0 :backcolor gui-color} ;-600
            {:name :sentence-parser :px 400 :py -300 :backcolor util-color}       ;-500
            {:name :task-creator :px 400 :py -150 :backcolor task-color}
            ;{:name :input-load-reducer :px 400 :py -325}
            {:name :operator-executor :px -100 :py -150 :backcolor [255 200 200]}
            ;{:name :event-buffer :px 200 :py 150}
            {:name :inference-request-router :px 900 :py 450 :backcolor derived-task-color}
            {:name :general-inferencer :px 900 :py 300 :backcolor derived-task-color}
            {:name :derived-load-reducer :px 900 :py 150 :backcolor derived-task-color}
            #_{:name :event-selector :px 600 :py 150 :backcolor task-color}
            #_{:name :event-bag :px 775 :py 150 :backcolor task-color}
            {:name :concept-selector :px -100 :py 300 :backcolor concept-color}
            {:name :concept-bag :px -100 :py 450 :backcolor concept-color}
            {:name :output :px 575 :py -400 :backcolor gui-color}])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def edges [{:name &quot;      :do-inference-msg&quot; :from :inference-request-router :to :general-inferencer :unidirectional true}
            {:name &quot;:create-concept-msg&quot; :from :task-dispatcher :to :concept-manager :unidirectional true}
            {:name &quot;:task-msg&quot; :from :concept-manager :to :task-dispatcher :unidirectional true}
            ;{:from :task-dispatcher :to :event-buffer :unidirectional true}
            {:name &quot;                  :do-inference-msg&quot; :from :concepts :to :inference-request-router :unidirectional true}
            {:name &quot;:operator-execution-msg&quot; :from :concepts :to :operator-executor :unidirectional true}
            {:name &quot;:sentence-msg&quot; :from :operator-executor :to :task-creator :unidirectional true}
            #_{:name &quot;:do-inference-msg&quot; :from :event-selector :to :general-inferencer :unidirectional true}
            {:name &quot;:sentence-msg&quot; :from :sentence-parser :to :task-creator :unidirectional true}
               ;{:from :sentence-parser :to :input-load-reducer}
               ;{:from :input-load-reducer :to :task-creator}
            {:name &quot;:derived-sentence-msg&quot; :from :general-inferencer :to :derived-load-reducer :unidirectional true}
            {:name &quot;           :derived-sentence-msg&quot; :from :derived-load-reducer :to :task-creator :unidirectional true}
            {:name &quot;:task-msg&quot; :from :task-creator :to :task-dispatcher :unidirectional true}
            {:name &quot;:inference-request-msg&quot; :from :concept-selector :to :concepts :unidirectional true}
            {:name &quot;add element&quot; :from :concept-manager :to :concept-bag :unidirectional true}
            {:name &quot;:task-msg :link-feedback-msg&quot; :from :task-dispatcher :to :concepts :unidirectional true}
            {:name &quot;takeout&quot; :from :concept-bag :to :concept-selector :unidirectional true}
            #_{:name &quot;         add element&quot; :from :task-dispatcher :to :event-bag :unidirectional true}])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def graph-actors [nodes edges actor-level-width actor-level-height])</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#gui.globals" name="gui.globals"><h1 class="project-name">gui.globals</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns gui.globals)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def init-size 800)
(def task-filter (atom ))
(def input-string (atom (atom )))
(def invert-colors (atom false))
(def prio-threshold (atom 0.0))
(def link-labels (atom false))
(def concept-filter (atom ))
(def inputstr (atom ))
(def speed (atom &quot;medium&quot;))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#gui.gui" name="gui.gui"><h1 class="project-name">gui.gui</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns gui.gui
  (:require [seesaw.core :refer :all]
            [gui.globals :refer :all]
            [co.paralleluniverse.pulsar.actors :refer [whereis cast!]]
            [clojure.string :as str]
            [gui.gui-utils :refer :all]
            [narjure.core :refer [start-timers shutdown run stop-timers]]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def backcolor [230 230 230])
(def gui-width 50)
(def gui-height 25)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def nodes [{:name :send :px 500 :py -325 :onclick (fn [state]
                                                     (input-str (deref inputstr))
                                                     (swap! inputstr (fn [st] ))) :backcolor backcolor}
            {:name :paste :px 350 :py -325 :onclick (fn [state]
                                                     (input-str (slurp-clipboard)))
             :backcolor backcolor}
            {:name :clear :px 400 :py -325 :onclick (fn [state]
                                                     (swap! inputstr (fn [st] ))) :backcolor backcolor}
            {:name :pop-up :px 450 :py -325 :onclick (fn [state]
                                                      (cast! (whereis :sentence-parser) [:narsese-string-msg (str (input &quot;Add Narsese&quot; :to-string :name) &quot;\n&quot;)]))
             :backcolor backcolor}
            #_{:name :resume :px 450 :py -525 :onclick (fn [state]
                                                      (start-timers))
             :backcolor backcolor}
            #_{:name :pause :px 500 :py -525 :onclick (fn [state]
                                                       (stop-timers))
             :backcolor backcolor}
            #_{:name :off :px 650 :py -525 :onclick (fn [state]
                                                       (shutdown))
             :backcolor backcolor}
            #_{:name :start :px 700 :py -525 :onclick (fn [state]
                                                       (run))
             :backcolor backcolor}
            #_{:name :color :px 1000 :py -525 :onclick (fn [state]
                                                      (reset! invert-colors (not @invert-colors)))
             :backcolor backcolor}
            #_{:name :+prioTh. :px 1100 :py -525 :onclick (fn [state]
                                                       (reset! prio-threshold (+ @prio-threshold 0.1)))
             :backcolor backcolor}
            #_{:name :-prioTh. :px 1200 :py -525 :onclick (fn [state]
                                                            (reset! prio-threshold (- @prio-threshold 0.1)))
             :backcolor backcolor}
            #_{:name :edgeInf. :px 1300 :py -525 :onclick (fn [state]
                                                       (reset! link-labels (not @link-labels)))
             :backcolor backcolor}])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def graph-gui [nodes [] gui-width gui-height])</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#gui.gui-utils" name="gui.gui-utils"><h1 class="project-name">gui.gui-utils</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns gui.gui-utils
  (:require [seesaw.core :refer :all]
            [gui.globals :refer :all]
            [co.paralleluniverse.pulsar.actors :refer [whereis cast!]]
            [clojure.string :as str]
            [narjure.core :refer [start-timers shutdown run stop-timers]]))</pre></td></tr><tr><td class="docs"><p>Inverts the color in Lense</p>
</td><td class="codes"><pre class="brush: clojure">(defn invert-color
  [[colr colg colb cola]]
  (if (= (deref invert-colors) true)
    [(- 255 colr) (- 255 colg) (- 255 colb) (if cola cola 255)]
    [colr colg colb (if cola cola 255)]))</pre></td></tr><tr><td class="docs"><p>Invert a color component</p>
</td><td class="codes"><pre class="brush: clojure">(defn invert-comp
  [v]
  (if (= (deref invert-colors) true)
    (- 255 v)
    v))</pre></td></tr><tr><td class="docs"><p>Extract system clipboard</p>
</td><td class="codes"><pre class="brush: clojure">(defn get-clipboard
  []
  (.getSystemClipboard (java.awt.Toolkit/getDefaultToolkit)))</pre></td></tr><tr><td class="docs"><p>Get the system clipboard content</p>
</td><td class="codes"><pre class="brush: clojure">(defn slurp-clipboard
  []
  (try
    (.getTransferData (.getContents (get-clipboard) nil) (java.awt.datatransfer.DataFlavor/stringFlavor))
    (catch Exception e nil)))</pre></td></tr><tr><td class="docs"><p>Write something into the system clipboard</p>
</td><td class="codes"><pre class="brush: clojure">(defn spit-clipboard
  [text]
  (try
    (.setContents (get-clipboard) (java.awt.datatransfer.StringSelection. text) nil)
    (catch Exception e nil)))</pre></td></tr><tr><td class="docs"><p>Input Narsese by sending the narsese-string to sentence parser</p>
</td><td class="codes"><pre class="brush: clojure">(defn input-str
  [st]
  (println (str &quot;input narsese &quot; st))
  (doseq [x (str/split st #&quot;\n&quot;)]
    (cast! (whereis :sentence-parser) [:narsese-string-msg x])))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#gui.hnav" name="gui.hnav"><h1 class="project-name">gui.hnav</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns gui.hnav
  (:require [quil.core :as q]
            [gui.gui-utils :refer :all]
            [gui.globals :refer :all]))</pre></td></tr><tr><td class="docs"><p>Returns the window width</p>
</td><td class="codes"><pre class="brush: clojure">(defn width
  []
  (try (if (or (= nil q/width) (= nil (q/width)))
         init-size
         (q/width))
       (catch Exception e init-size)))</pre></td></tr><tr><td class="docs"><p>Returns the window height</p>
</td><td class="codes"><pre class="brush: clojure">(defn height
  []
  (try (if (or (= nil q/height) (= nil (q/height)))
         init-size
         (q/height))
       (catch Exception e init-size)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn speedhelper
  (^double [^double zoom ^double coord ^double dif ^double wh]
   (* (/ 1.0 zoom) (+ coord (- dif) (- (/ wh 2.0))))))</pre></td></tr><tr><td class="docs"><p>Transform the mouse coordinates to world coordinates</p>
</td><td class="codes"><pre class="brush: clojure">(defn mouse-to-world-coord-x
  [state x]
  (speedhelper (:zoom state) x (:difx state) (width)))</pre></td></tr><tr><td class="docs"><p>Transform the mouse coordinates to world coordinates</p>
</td><td class="codes"><pre class="brush: clojure">(defn mouse-to-world-coord-y
  [state y]
  (speedhelper (:zoom state) y (:dify state) (height)))</pre></td></tr><tr><td class="docs"><p>The hnav navigation world transformation</p>
</td><td class="codes"><pre class="brush: clojure">(defn transform
  [{:keys [difx dify zoom]}]
  (q/translate (+ difx (* 0.5 (width)))
               (+ dify (* 0.5 (height))))
  (q/scale zoom zoom))</pre></td></tr><tr><td class="docs"><p>A helper for string printing</p>

<p>a utility for copy paste todo cleanup</p>
</td><td class="codes"><pre class="brush: clojure">(defn display-string
  [debugmessage name]
  (clojure.string/replace (str (if (&gt; (count (debugmessage name)) 1)
                                 (if (not= &quot;&quot; (deref (second (debugmessage name))))
                                   (str (deref (second (debugmessage name))) &quot;\n&quot;))
                                 &quot;&quot;)
                               ((first (debugmessage name)))) #&quot;§&quot; &quot;\n&quot;))</pre></td></tr><tr><td class="docs"><p>HNAV implementation</p>
</td><td class="codes"><pre class="brush: clojure">(defn mouse-pressed
  [graphs debugmessage hud state event]                           ;also HGUI click check here
  (when (not= [] graphs)
    (doseq [[V E w h] @graphs]
      (doseq [v V]
        (let [px (:px v)
              py (:py v)
              mousex (if hud (:x event) (mouse-to-world-coord-x state (:x event)))
              mousey (if hud (:y event) (mouse-to-world-coord-y state (:y event)))]
          (when (and (&gt; mousex px) (&gt; mousey py)
                     (&lt; mousex (+ px (if (:custom-w v) (:custom-w v) w)))
                     (&lt; mousey (+ py (if (:custom-h h) (:custom-h h) h))))
            (when (not (= (:onclick v) nil))
              ((:onclick v) state))
            (when (not= nil (:name v))
              (spit-clipboard (str (:name v))))
            (when (contains? debugmessage (:name v))
              (let [debugentry ((:name v) debugmessage)]
                (when (not= nil debugentry)
                  (spit-clipboard (str (slurp-clipboard) (display-string debugmessage (:name v))))
                  (when (&gt; (count debugentry) 1)
                    (reset! input-string (second debugentry)))))))))))
  (assoc state :savepx (:x event) :savepy (:y event) :md true))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn mouse-dragged [state event]
  (-&gt; state
      (assoc :difx (+ (:difx state) (- (:x event) (:savepx state)))
             :dify (+ (:dify state) (- (:y event) (:savepy state)))
             :savepx (:x event)
             :savepy (:y event))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def scrollcamspeed 1.3)
(defn mouse-wheel [state mouse-scroll]
  (let [zoom-before (:zoom state)
        state2 (if (&gt; mouse-scroll 0)
                 (assoc state :zoom (/ (:zoom state) scrollcamspeed))
                 (assoc state :zoom (* (:zoom state) scrollcamspeed)))]
    (-&gt; state2
        (assoc :difx (* (:difx state2) (/ (:zoom state2) zoom-before)))
        (assoc :dify (* (:dify state2) (/ (:zoom state2) zoom-before))))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def states {:difx   (- (/ (width) 2))
             :dify   (- (/ (height) 2))
             :savepx 0.0
             :savepy 0.0
             :zoom   1.0})</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#gui.hud" name="gui.hud"><h1 class="project-name">gui.hud</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns gui.hud
  (:require [seesaw.core :refer :all]
            [gui.globals :refer :all]
            [co.paralleluniverse.pulsar.actors :refer [whereis cast!]]
            [clojure.string :as str]
            [narjure.core :refer [start-timers shutdown run stop-timers]]
            [gui.gui-utils :refer :all]
            [narjure.defaults :refer :all]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def backcolor [230 230 230 100])
(def hud-width 50)
(def hud-height 25)</pre></td></tr><tr><td class="docs"><p>TODO put at proper place</p>
</td><td class="codes"><pre class="brush: clojure">(defn set-fast-speed []
  &quot;Sets the speed of the reasoner to fast&quot;
  (reset! system-tick-interval system-tick-interval-fast)
  (reset! inference-tick-interval inference-tick-interval-fast)
  (reset! speed &quot;fast&quot;)
  (stop-timers)
  (start-timers))</pre></td></tr><tr><td class="docs"><p>TODO put at proper place</p>
</td><td class="codes"><pre class="brush: clojure">(defn set-medium-speed []
  &quot;Sets the speed of the reasoner to fast&quot;
  (reset! system-tick-interval system-tick-interval-medium)
  (reset! inference-tick-interval inference-tick-interval-medium)
  (reset! speed &quot;medium&quot;)
  (stop-timers)
  (start-timers))</pre></td></tr><tr><td class="docs"><p>TODO put at proper place</p>
</td><td class="codes"><pre class="brush: clojure">(defn set-slow-speed []
  &quot;Sets the speed of the reasoner to slow&quot;
  (reset! system-tick-interval system-tick-interval-slow)
  (reset! inference-tick-interval inference-tick-interval-slow)
  (reset! speed &quot;slow&quot;)
  (stop-timers)
  (start-timers))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn swap-speed []
  (if (= @speed &quot;slow&quot;)
    (set-fast-speed)
    (if (= @speed &quot;fast&quot;)
      (set-medium-speed)
      (set-slow-speed))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def nodes [{:name :pop-up :px 710 :py 0 :onclick (fn [state]
                                                       (cast! (whereis :sentence-parser) [:narsese-string-msg (str (input &quot;Add Narsese&quot; :to-string :name) &quot;\n&quot;)]))
             :backcolor backcolor}
            {:name :paste :px 760 :py 0 :custom-w 40 :onclick (fn [state]
                                                      (input-str (slurp-clipboard)))
             :backcolor backcolor}
            {:name :&gt; :px 0 :py 0 :onclick (fn [state]
                                                  (stop-timers)
                                                  (start-timers))
             :displaysize 10
             :backcolor backcolor}
            {:name :|| :px 50 :py 0 :custom-w 25 :onclick (fn [state]
                                                     (stop-timers))
             :backcolor backcolor}
            {:name :&gt;| :custom-w 25 :px 75 :py 0 :onclick (fn [state]
                                                               (cast! (whereis :concept-selector) [:inference-tick-msg])
                                                               (cast! (whereis :task-creator) [:system-time-tick-msg])
                                                               (cast! (whereis :derived-load-reducer) [:system-time-tick-msg])
                                                               (cast! (whereis :forgettor) [:system-time-tick-msg]))
             :backcolor backcolor}
            {:name :reset :custom-w 35 :px 150 :py 0 :onclick (fn [state]
                                                              (shutdown)
                                                              (run))
             :backcolor backcolor}
            {:name :save :custom-w 35 :px 185 :py 0 :onclick (fn [state]
                                                               (cast! (whereis :concept-manager) [:persist-state-msg []]))
             :backcolor backcolor}
            {:name :load :custom-w 35 :px 220 :py 0 :onclick (fn [state]
                                                               (shutdown)
                                                               (run)
                                                               (cast! (whereis :concept-manager) [:load-state-msg []]))
             :backcolor backcolor}
            {:name :color :custom-w 30 :px 275 :py 0 :onclick (fn [state]
                                                       (reset! invert-colors (not @invert-colors)))
             :backcolor backcolor}
            {:name :speed :px 100 :py 0 :onclick (fn [state]
                                                   (swap-speed))
             :displaysize 10
             :backcolor backcolor}
            {:name :+prioTh. :px 305 :py 0 :onclick (fn [state]
                                                      (reset! prio-threshold (+ @prio-threshold 0.1)))
             :displaysize 10
             :backcolor backcolor}
            {:name :-prioTh. :px 355 :py 0 :onclick (fn [state]
                                                            (reset! prio-threshold (- @prio-threshold 0.1)))
             :backcolor backcolor}
            {:name :details :custom-w 40 :px 405 :py 0 :onclick (fn [state]
                                                            (reset! link-labels (not @link-labels)))
             :backcolor backcolor}
            {:name :send :px 660 :py 0 :onclick (fn [state]
                                                     (input-str (deref inputstr))
                                                     (swap! inputstr (fn [st] ))) :backcolor backcolor}
            {:name :input :px 460 :custom-w 200 :py 0 :backcolor backcolor :displaysize 10}
            ])</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def hud [nodes [] hud-width hud-height])</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#gui.lense" name="gui.lense"><h1 class="project-name">gui.lense</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns gui.lense
  (:require [quil.core :as q]
            [quil.middleware :as m]
            [gui.actors :refer [graph-actors]]
            [gui.gui-utils :refer :all]
            [gui.gui :refer [graph-gui]]
            [nal.deriver.projection-eternalization :refer [project-eternalize-to]]
            [gui.hud :refer [hud]]
            [gui.hnav :as hnav]
            [seesaw.core :refer :all]
            [gui.globals :refer :all]
            [narjure.core :as nar]
            [co.paralleluniverse.pulsar.actors :refer [whereis cast!]]
            [narjure.general-inference.inference-request-router :as inference-request-router]
            [narjure.general-inference.concept-selector :as concept-selector]
            [narjure.general-inference.general-inferencer :as general-inferencer]
            [narjure.memory-management.concept-manager :as concept-manager]
            [narjure.memory-management.task-dispatcher :as task-dispatcher]
            [narjure.perception-action.operator-executor :as operator-executor]
            [narjure.perception-action.sentence-parser :as sentence-parser]
            [narjure.perception-action.task-creator :as task-creator]
    ;[narjure.perception-action.input-load-reducer :as input-load-reducer]
            [narjure.perception-action.derived-load-reducer :as derived-load-reducer]
            [narjure.memory-management.concept :as concepts]
            [narjure.global-atoms :refer :all]
            [narjure.debug-util :refer :all]
            [narjure.bag :as b]
            [narjure.defaults :refer [priority-threshold max-concept-selections max-tasks]]
            [clojure.set :as set]
            [clojure.string :as str])
  (:gen-class))</pre></td></tr><tr><td class="docs"><p>Bag string format: each id goes into a new line</p>
</td><td class="codes"><pre class="brush: clojure">(defn bag-format
  [st]
  (clojure.string/replace (clojure.string/replace st &quot;(:id&quot; &quot;\n( :id&quot;) &quot;(\n( &quot; &quot;((&quot;))</pre></td></tr><tr><td class="docs"><p>Filter the bag for these entries which contain the filter content</p>
</td><td class="codes"><pre class="brush: clojure">(defn bagfilter
  [fil bag]
  (apply vector (filter (fn [x]
                          (every? (fn [y] (.contains (narsese-print x) y))
                                  (str/split (deref fil) #&quot;\n&quot;))) bag)))</pre></td></tr><tr><td class="docs"><p>Show the bag, with a string length limit.</p>
</td><td class="codes"><pre class="brush: clojure">(defn bagshow
  [bag filteratom]
  (bag-format (limit-string
                (narsese-print (bagfilter filteratom
                                          (:priority-index bag))) 20000)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def debugmessage {:inference-request-router [(fn [] (deref inference-request-router/display)) inference-request-router/search]
                   :concept-selector         [(fn [] (deref concept-selector/display)) concept-selector/search]
                   :general-inferencer       [(fn [] (deref general-inferencer/display)) general-inferencer/search]
                   :concept-manager          [(fn [] (deref concept-manager/display)) concept-manager/search]
                   :task-dispatcher          [(fn [] (deref task-dispatcher/display)) task-dispatcher/search]
                   :operator-executor        [(fn [] (deref operator-executor/display)) operator-executor/search]
                   :sentence-parser          [(fn [] (deref sentence-parser/display)) sentence-parser/search]
                   :task-creator             [(fn [] (deref task-creator/display)) task-creator/search]
                   :concepts                 [(fn [] (deref concepts/display)) concepts/search]
                   :concept-bag              [(fn [] (bagshow @c-bag concept-filter)) concept-filter]
                   :derived-load-reducer     [(fn [] (deref derived-load-reducer/display)) derived-load-reducer/search]
                   :input                    [(fn [] ) inputstr]
                   :output                   [(fn [] (deref output-display)) output-search]
                   :+prioTh.                 [(fn [] (deref prio-threshold))]
                   :speed                    [(fn [] (deref speed))]
                   :&gt;                   [(fn [] (deref nars-time))]})</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def static-graphs [graph-actors graph-gui])
(def graphs (atom static-graphs))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn setup []
  (q/frame-rate 30)
  ;(nar/run)
  (merge hnav/states {}))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn update [state] state)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn nameof [a]
  (if (string? a) a (name a)))</pre></td></tr><tr><td class="docs"><p>Draw an actor block</p>
</td><td class="codes"><pre class="brush: clojure">(defn draw-actor
  [{:keys [name px py backcolor frontcolor displaysize titlesize stroke-weight custom-w custom-h]} node-width node-height]
  (q/stroke-weight (if (= nil stroke-weight) 1.0 stroke-weight))
  (apply q/fill (invert-color (if (= backcolor nil) [255 255 255] backcolor)))
  (q/rect px py (if custom-w custom-w node-width) (if custom-h custom-h node-height))
  (apply q/fill (invert-color (if (= frontcolor nil) [0 0 0] frontcolor)))
  (q/text-size (if (= nil titlesize) 10.0 titlesize))
  (q/text (nameof name) (+ px 5) (+ py (if (= nil titlesize) 10.0 titlesize)))
  (q/text-size (if (= displaysize nil) 2.0 displaysize))
  (when (contains? debugmessage name)
    (q/text (hnav/display-string debugmessage name)
            (+ px 5) (+ py 20)))
  (q/text-size 2.0))</pre></td></tr><tr><td class="docs"><p>Checks whether the point p is inside of the double-sized screen.</p>
</td><td class="codes"><pre class="brush: clojure">(defn in-picture
  [state p hud]
  (if hud
    true
    (if (and (&gt; (:px p) (hnav/mouse-to-world-coord-x state (- (hnav/width))))
             (&lt; (:px p) (hnav/mouse-to-world-coord-x state (+ (hnav/width) (hnav/width))))
             (&gt; (:py p) (hnav/mouse-to-world-coord-y state (- (hnav/height))))
             (&lt; (:py p) (hnav/mouse-to-world-coord-y state (+ (hnav/height) (hnav/height)))))
      true
      false)))</pre></td></tr><tr><td class="docs"><p>Checks whether the point p is inside of the screen.</p>
</td><td class="codes"><pre class="brush: clojure">(defn in-picture-aggressive
  [state p hud]
  (if hud
    true
    (if (and (&gt; (:px p) (hnav/mouse-to-world-coord-x state 0.0))
             (&lt; (:px p) (hnav/mouse-to-world-coord-x state (hnav/width)))
             (&gt; (:py p) (hnav/mouse-to-world-coord-y state 0.0))
             (&lt; (:py p) (hnav/mouse-to-world-coord-y state (hnav/height))))
      true
      false)))</pre></td></tr><tr><td class="docs"><p>Draw a graph, its nodes and edges and their contents</p>
</td><td class="codes"><pre class="brush: clojure">(defn draw-graph
  [state [nodes edges node-width node-height] hud]
  (let [prefer-id (fn [n] (if (= nil (:id n))
                            (:name n)
                            (:id n)))]
    (doseq [c edges]
      (when (and (some #(= (:from c) (prefer-id %)) nodes)
                 (some #(= (:to c) (prefer-id %)) nodes))
        (let [pxtransform (fn [x] (+ (:px x) (/ node-width 2.0)))
              pytransform (fn [y] (+ (:py y) (/ node-height 2.0)))
              left (first (filter #(= (:from c) (prefer-id %)) nodes))
              right (first (filter #(= (:to c) (prefer-id %)) nodes))
              middle {:px (/ (+ (:px left) (:px right)) 2.0)
                      :py (/ (+ (:py left) (:py right)) 2.0)}
              namepos {:px (/ (+ (* 0.6 (:px left)) (* 0.4 (:px right))) 1.0)
                       :py (+ 3 (/ (+ (* 0.6 (:py left)) (* 0.4 (:py right))) 1.0))}
              target (if (not= true (:unidirectional c))
                       right middle)
              weight (if (not= nil (:stroke-weight c))
                       (:stroke-weight c)
                       0.5)
              left-x (pxtransform left) left-y (pytransform left)
              right-x (pxtransform right) right-y (pytransform right)
              target-x (pxtransform target) target-y (pytransform target)
              middle-x (pxtransform middle) middle-y (pytransform middle)
              namepos-x (pxtransform namepos) namepos-y (pytransform namepos)
              pointf (fn [a b] {:px a :py b})
              name (:name c)]
          (when (or (:no-in-picture-check c)
                    (in-picture state (pointf left-x left-y) hud)
                    name
                    (and @link-labels
                         (in-picture state (pointf namepos-x namepos-y) hud)))
            (let [eval-color (if (= nil (:link-color c) )
                               (invert-color [0 0 0])
                               (invert-color (:link-color c)))
                  col eval-color
                  r (first col)
                  g (second col)
                  b (nth col 2)]
              (q/stroke r g b)
              (q/stroke-weight (* weight 2.0))
              (q/line left-x left-y
                      middle-x target-y)
              (when (and (:unidirectional c)
                         (not (:opposite-edge-exists c)))
                (if (:ghost-opposite c)
                  (do
                    (q/stroke (invert-comp 210.0))
                    (q/stroke-weight 0.15))
                  (do
                    (q/stroke-weight weight)))
                (q/line right-x right-y
                        middle-x middle-y))
              (when (not= nil name)
                (q/text (str name) namepos-x namepos-y))))))))
  (q/stroke (first (invert-color [0 0 0])))
  (doseq [a nodes]
    (when (in-picture state (assoc a :px (+ (:px a) (/ node-width 2.0))
                                     :py (+ (:py a) (/ node-height 2.0))) hud)
      (draw-actor a node-width node-height))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def selected-concept (atom []))</pre></td></tr><tr><td class="docs"><p>copy of draw below marked as draw2</p>
</td><td class="codes"><pre class="brush: clojure">(defn draw [state]
  (q/background (first (invert-color [255 255 255])))
  (q/reset-matrix)
  (q/push-matrix)
  (hnav/transform state)
  (doseq [g @graphs]
    (draw-graph state g false))
  ;(reset! graphs static-graphs)
  ;concept graph
  (when (&gt; (hnav/mouse-to-world-coord-x state (hnav/width)) 1600)
    (try (let [elems (apply vector (:priority-index (deref c-bag)))
               a 75.0
               pxfun (fn [ratio] (+ 3500 (* a ratio (Math/cos ratio))))
               pyfun (fn [ratio] (+ 200 (* a ratio (Math/sin ratio))))
               isin
               (apply set/union
                      (for [i (range (count elems))]
                        (let [elem (elems i)
                              ratio (* 30.0 (+ 0.10 (/ i (count elems))))
                              px (pxfun ratio)
                              py (pyfun ratio)]
                          (when ((if @link-labels in-picture in-picture-aggressive) state {:px px :py py} false)
                            (set/union (set (keys (@lense-termlinks (:id elem))))
                                       #{(:id elem)})))))
               nodes (for [i (range (count elems))]
                       (let [elem (elems i)
                             ratio (* 30.0 (+ 0.10 (/ i (count elems))))
                             id (:id elem)
                             px (pxfun ratio)
                             py (pyfun ratio)
                             priority (:priority elem)
                             show-concept ((:elements-map (deref c-bag)) id)
                             quality (:quality show-concept)
                             observable (:observable show-concept)]
                         (when (try
                                 (and
                                   (every? (fn [x] (.contains (narsese-print id) x))
                                           (str/split (deref concept-filter) #&quot;\n&quot;))
                                      (&gt; priority priority-threshold)
                                      (&gt; priority @prio-threshold)
                                      (or (isin id)
                                          ((if @link-labels in-picture in-picture-aggressive) state {:px px :py py} false)))
                                 (catch Exception e false))
                           {:name          (str &quot;\n&quot; (narsese-print id)
                                                (if (= id @selected-concept)
                                                  (let [truth  (:truth (lense-max-statement-confidence-projected-to-now id :belief nil))
                                                        desire (:truth (lense-max-statement-confidence-projected-to-now id :goal nil))]
                                                    (str &quot;\nfilter: &quot; @task-filter &quot;priority: &quot; priority &quot; &quot; &quot;quality: &quot; quality &quot; &quot;
                                                        (when truth &quot;truth: &quot; truth &quot; &quot;)
                                                        (when desire &quot;desire: &quot; desire &quot; &quot;)
                                                         (when observable &quot;observable&quot;)
                                                         &quot;\n&quot;
                                                        (bag-format
                                                          (limit-string (narsese-print (apply vector
                                                                                              (if @link-labels
                                                                                                (bagfilter task-filter (:elements-map (@lense-taskbags id)))
                                                                                                (let [curbag (@lense-taskbags id)
                                                                                                      pindex (:priority-index curbag)]
                                                                                                  (map (fn [has-id]
                                                                                                         (let [task (:task (first (b/get-by-id curbag (:id has-id))))]
                                                                                                           (assoc has-id :truth (:truth task)
                                                                                                                         :occurrence (if (= (:occurrence task) :eternal)
                                                                                                                                       :eternal
                                                                                                                                       (- (:occurrence task) @nars-time))
                                                                                                                         :quality (nth (:budget task) 2)
                                                                                                                         :solution (when (:solution task)
                                                                                                                                     {:statement  (:statement (:solution task))
                                                                                                                                      :truth      (:truth (:solution task))
                                                                                                                                      :occurrence (:occurrence (:solution task))}))))
                                                                                                       (bagfilter task-filter (:priority-index (@lense-taskbags id)))))))) 20000))))))       ;&quot;\n&quot; @lense-termlinks
                            :px            px
                            :py            py
                            :displaysize   1.0
                            :backcolor     [(- 255 (* priority 255.0)) 255 255]
                            :titlesize     2.0
                            :stroke-weight 0.5
                            :id            id
                            :onclick       (fn [state]
                                             (reset! input-string task-filter)
                                             (reset! selected-concept id))})))
               edges (for [n nodes
                           [k [freq conf]] (@lense-termlinks (:id n))]
                       (let [red-blue-border 0.5
                             disttomiddle (Math/abs (- 0.5 freq))
                             rterm (/ (if (&gt;= freq red-blue-border) (* 510.0 disttomiddle) 0.0) 2.0)
                             bterm (/ (if (&lt; freq red-blue-border) (* 510.0 disttomiddle) 0.0) 2.0)]
                         {:from                 (:id n)
                          :to                   k :unidirectional true
                          :no-in-picture-check true
                          :stroke-weight        (* 0.5 conf)
                          :link-color           (if @invert-colors
                                                  (invert-color [(+ 128.0 rterm) 128.0 (+ 128.0 bterm)])
                                                  [0.0 (+ 0 rterm) (+ 0 bterm)])
                          :name                 (when @link-labels [freq conf])
                          :opposite-edge-exists (some (fn [[tl2 _]]
                                                        (= tl2 (:id n)))
                                                      (@lense-termlinks k))
                          :ghost-opposite       true}))
               concept-graph [(filter #(not= % nil) nodes) edges 10 10]]
           (reset! graphs (concat static-graphs [concept-graph])))
         (catch Exception e (println &quot;test&quot;))))
  (q/pop-matrix)
  (try
    (draw-graph state hud true)
    (catch Exception e ()))
  (draw-graph state hud true))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn key-pressed [state event]
  (let [name (name (:key event))
        code (:key-code event)]
    (swap! (deref input-string) (fn [inputstr] (str (if (not (= code 8))
                                                      inputstr (subs inputstr 0 (max 0 (dec (count inputstr)))))
                                                    (if (not (&gt; (count name) 1))
                                                      (if (not (= code 8))
                                                        name ) ))))
    state))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn lense-mousepress [state event]
  (hnav/mouse-pressed graphs debugmessage false state event)
  (hnav/mouse-pressed (atom [hud]) debugmessage true state event))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn -main []
  (q/defsketch example
              :size [(hnav/width) (hnav/height)]
              :setup setup
              :draw draw
              :update update
              :mouse-pressed lense-mousepress
              :mouse-dragged hnav/mouse-dragged
              :mouse-wheel hnav/mouse-wheel
              :key-pressed key-pressed
              :middleware [m/fun-mode]
              :features [:resizable]
              :title &quot;OpenNARS 2.0.0: Lense&quot;))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#examples.ircbot" name="examples.ircbot"><h1 class="project-name">examples.ircbot</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns examples.ircbot
  (:require [irclj.core :refer :all]
            [irclj.parser :refer :all]
            [narjure.global-atoms :refer :all]
            [narjure.core :as nar]
            [narjure.narsese :refer [parse2]]
            [narjure.sensorimotor :refer :all]
            [narjure.debug-util :refer :all]
            [gui.hud :refer [set-fast-speed]]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def channel &quot;#nars&quot;)
(def server &quot;irc.freenode.org&quot;)
(def port 6667)
(def bot-nick &quot;mr_nars&quot;)</pre></td></tr><tr><td class="docs"><p>(def bot-nick-password "password")</p>
</td><td class="codes"></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def state (atom {}))</pre></td></tr><tr><td class="docs"><p>Registers the operation and answer handler</p>
</td><td class="codes"><pre class="brush: clojure">(defn setup-nars
  [irc]
  (nars-register-operation 'op_talk (fn [args operationgoal]
                                      (let [msg (str &quot;NARS says &quot; args)]
                                        (println msg)
                                        (message irc channel msg)
                                        true)))
  (nars-register-answer-handler (fn [task solution]
                                  (let [msg (str &quot;NARS answer on &quot; (narsese-print (:statement task)) &quot;? is &quot; (task-to-narsese solution))]
                                    (println msg)
                                    (message irc channel msg)))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def help [
   &quot;Commands:&quot;
   &quot;!n {string} - input narsese.&quot;
   &quot;!s {string} - input sentence.&quot;
   &quot;!c {string} - show concept.&quot;
   &quot;!cs - show concepts.&quot;
   &quot;!r - reset NARS.&quot;
   &quot;!h - see this message.&quot;
])</pre></td></tr><tr><td class="docs"><p>Show a concept</p>
</td><td class="codes"><pre class="brush: clojure">(defn concept
  [concept-str]
  (try
    (let [statement (parse2 (str concept-str &quot;.&quot;))]
      (dissoc
        (first (narjure.bag/get-by-id @c-bag (:statement statement)))
        :ref))
    (catch Exception e (str &quot;Invalid narsese &quot; concept-str))))</pre></td></tr><tr><td class="docs"><p>Show all the concepts</p>
</td><td class="codes"><pre class="brush: clojure">(defn concepts
  []
  (:priority-index @c-bag))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn parse-narsese [string]
  &quot;Input the received Narsese into the system.&quot;
  (try
    (let [statement (parse2 string)]
      (nars-input-narsese string)
      (println (str &quot;NARS hears &quot; string))
      (str &quot;NARS hears &quot; string))
    (catch Exception e (str &quot;Invalid narsese &quot; string))))</pre></td></tr><tr><td class="docs"><p>NLP representation handling.</p>
</td><td class="codes"><pre class="brush: clojure">(defn parse-sentence
  [string event-symbol]
  (let [words (clojure.string/split string #&quot; &quot;)
        sentence (str &quot;&lt;(*,&quot; (clojure.string/join &quot;,&quot; words) &quot;) --&gt; SENTENCE&gt;. &quot; event-symbol)]
    (parse-narsese sentence)))</pre></td></tr><tr><td class="docs"><p>Resets the system</p>
</td><td class="codes"><pre class="brush: clojure">(defn reset-nars
  []
  (nar/shutdown)
  (nar/run)
  &quot;NARS reset&quot;)</pre></td></tr><tr><td class="docs"><p>Command interpreter</p>
</td><td class="codes"><pre class="brush: clojure">(defn user-said-in-channel
  [state nick said]
  (let [[command string] (clojure.string/split said #&quot; &quot; 2)]
    (case command
      (&quot;!n&quot; &quot;!nars&quot; &quot;!narsese&quot;)
        [(parse-narsese string) state]
      (&quot;!ss&quot; &quot;!static-sentence&quot;)
        [(parse-sentence string &quot;&quot;) state]
      (&quot;!s&quot; &quot;!sentence&quot;)
        [(parse-sentence string &quot;:|:&quot;) state]
      (&quot;!c&quot; &quot;!concept&quot;)
        [(concept string) state]
      (&quot;!cs&quot; &quot;!concepts&quot;)
        [(concepts) state]
      (&quot;!r&quot; &quot;!reset&quot;)
        [(reset-nars) state]
      (&quot;!h&quot; &quot;!help&quot;)
        [help]
      [nil])))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn handle-command [state command text nick]
  (case command
    &quot;PRIVMSG&quot; (user-said-in-channel state nick text)
    [nil state]))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn working-reply [irc m string]
  (let [m2 (if (.startsWith (:target m) &quot;#&quot;) m (assoc m :target (:nick m)))]
    (reply irc m2 string)))</pre></td></tr><tr><td class="docs"><p>Send a string message into the channel</p>
</td><td class="codes"><pre class="brush: clojure">(defn say!
  [irc m string]
  (if (nil? string)
    nil
    (working-reply irc m string)))</pre></td></tr><tr><td class="docs"><p>The message receive callback handler</p>
</td><td class="codes"><pre class="brush: clojure">(defn callback
  [irc args]
  (let [{text :text
         target :target
         nick :nick
         command :command} args]
    (let [[response, new_state] (handle-command @state command text nick)]
      (if (sequential? response)
        (doseq [line response]
          (say! irc args line))
        (say! irc args response))
      (reset! state new_state))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn debug-callback [irc &amp; args]
  (prn args)
  (println))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn -main [&amp; args]
  (println &quot;Connecting...&quot; server)
  (def irc (connect server port bot-nick :callbacks {:privmsg callback}))
  (setup-nars irc)
  ;(identify irc bot-nick-password)
  (println &quot;Joining&quot; channel)
  (join irc channel))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#examples.pong" name="examples.pong"><h1 class="project-name">examples.pong</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns examples.pong
  (:require [quil.core :as q]
            [quil.middleware :as m]
            [gui.hnav :as hnav]
            [gui.gui-utils :refer [invert-comp]]
            [narjure.global-atoms :refer :all]
            [narjure.core :as nar]
            [narjure.defaults :refer [max-term-complexity]]
            [narjure.sensorimotor :refer :all])
  (:gen-class))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def py (atom 280))
(def direction (atom 0))
(def barheight 125)
(def fieldmax 760)
(def fieldmin 20)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn with-print [x]
  #_(println (str x))
  x)</pre></td></tr><tr><td class="docs"><p>Registers the operations</p>
</td><td class="codes"><pre class="brush: clojure">(defn setup-pong
  []
  (reset! max-term-complexity 21)
  (nars-input-narsese &quot;&lt;ballpos --&gt; [equal]&gt;! :|:&quot;)
  (q/frame-rate 100)
  (nars-register-operation 'op_up (fn [args operationgoal]
                                    (do
                                      (when (= (:source operationgoal) :derived)
                                        #_(println &quot;system decided up&quot;))
                                      (reset! direction -1)
                                      (with-print (not= @py fieldmin)))))
  (nars-register-operation 'op_down (fn [args operationgoal]
                                      (do
                                        (when (= (:source operationgoal) :derived)
                                          #_(println &quot;system decided down&quot;))
                                        (reset! direction 1)
                                        (with-print (not= @py (- fieldmax barheight (- fieldmin)))))))
  (merge hnav/states {:ball-px 380
                      :ball-py 400
                      :direction-x 1
                      :direction-y 1
                      :iteration 0}))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">&quot;
&lt;(&amp;/,(&amp;/,&lt;ballpos --&gt; [below]&gt;,i4,&lt;(*,{SELF}) --&gt; op_down&gt;),i4) =/&gt; &lt;ballpos --&gt; [equal]&gt;&gt;.
&lt;(&amp;/,(&amp;/,&lt;ballpos --&gt; [above]&gt;,i4,&lt;(*,{SELF}) --&gt; op_up&gt;),i4) =/&gt; &lt;ballpos --&gt; [equal]&gt;&gt;.
&quot;</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def allow-continuous-feedback true)
(def updown-state (atom &quot;equal&quot;))</pre></td></tr><tr><td class="docs"><p>World state transition</p>
</td><td class="codes"><pre class="brush: clojure">(defn update-pong
  [state]
  (when (= @direction -1)
    (reset! py (+ @py -3)))
  (when (= @direction 1)
    (reset! py (+ @py 3)))
  (when (= (mod (:iteration state) 25) 0)
    (println (str &quot;above truth &quot; (vec (:truth (lense-max-statement-confidence-projected-to-now '[--&gt; ballpos [int-set above]] :belief :event)))
                  &quot; below truth &quot; (vec (:truth (lense-max-statement-confidence-projected-to-now '[--&gt; ballpos [int-set below]] :belief :event)))
                  &quot; equal truth &quot; (vec (:truth (lense-max-statement-confidence-projected-to-now '[--&gt; ballpos [int-set equal]] :belief :event)))))
    (nars-input-narsese &quot;&lt;ballpos --&gt; [equal]&gt;! :|:&quot;))
  (when (= (mod (:iteration state) 125) 1)
    (println &quot;rand action&quot;)
    (nars-input-narsese (str (rand-nth [&quot;&lt;(*,{SELF}) --&gt; op_up&gt;! :|:&quot;
                                        &quot;&lt;(*,{SELF}) --&gt; op_down&gt;! :|:&quot;
                                        #_&quot;&lt;(*,{SELF}) --&gt; op_stop&gt;! :|:&quot;]))))
  ;also give info from time to time
  #_(when (= (mod (:iteration state) 80) 0)                    ;1
    #_(nars-input-narsese (str &quot;&lt;{&quot; (int (* 100 (quot (:ball-py state) 100))) &quot;} --&gt; ballpos&gt;. :|:&quot; ))
    #_(nars-input-narsese (str &quot;&lt;{&quot; (int (* 100 (quot @py 100))) &quot;} --&gt; barpos&gt;. :|:&quot; ))
    (if (and (&gt;= (:ball-py state) @py)
             (&lt;= (:ball-py state) (+ @py barheight)))
      (when true
        (nars-input-narsese &quot;&lt;ballpos --&gt; [equal]&gt;. :|: %1.0;0.9%&quot;)
        (reset! updown-state &quot;equal&quot;)
        #_(when allow-continuous-feedback
            ;(println &quot;good NARS&quot;)
            (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %1.0;0.9%&quot;)))
      (if (&gt; (:ball-py state) @py)
        (when true
          (nars-input-narsese (str &quot;&lt;ballpos --&gt; [below]&gt;. :|:&quot;))
          (reset! updown-state &quot;below&quot;)
          #_(when allow-continuous-feedback
              ;(println &quot;bad NARS&quot;)
              (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;)))
        (when true
          (nars-input-narsese (str &quot;&lt;ballpos --&gt; [above]&gt;. :|:&quot;))
          (reset! updown-state &quot;above&quot;)
          #_(when allow-continuous-feedback
              ;(println &quot;bad NARS&quot;)
              (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;))))))
  (when (= (mod (:iteration state) 1) 0)                    ;1
    #_(nars-input-narsese (str &quot;&lt;{&quot; (int (* 100 (quot (:ball-py state) 100))) &quot;} --&gt; ballpos&gt;. :|:&quot; ))
    #_(nars-input-narsese (str &quot;&lt;{&quot; (int (* 100 (quot @py 100))) &quot;} --&gt; barpos&gt;. :|:&quot; ))
    (if (and (&gt;= (:ball-py state) @py)
             (&lt;= (:ball-py state) (+ @py barheight)))
      (when (not= @updown-state &quot;equal&quot;)
        (nars-input-narsese &quot;&lt;ballpos --&gt; [equal]&gt;. :|: %1.0;0.9%&quot;)
        #_(nars-input-narsese &quot;&lt;ballpos --&gt; [above]&gt;. :|: %0%&quot;)
        #_(nars-input-narsese &quot;&lt;ballpos --&gt; [below]&gt;. :|: %0%&quot;)
        (reset! updown-state &quot;equal&quot;)
        #_(when allow-continuous-feedback
            ;(println &quot;good NARS&quot;)
            (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %1.0;0.9%&quot;)))
      (if (&gt; (:ball-py state) @py)
        (when (not= @updown-state &quot;below&quot;)
          (nars-input-narsese &quot;&lt;ballpos --&gt; [below]&gt;. :|:&quot;)
          #_(nars-input-narsese &quot;&lt;ballpos --&gt; [above]&gt;. :|: %0%&quot;)
          #_(nars-input-narsese &quot;&lt;ballpos --&gt; [equal]&gt;. :|: %0%&quot;)
          (reset! updown-state &quot;below&quot;)
          #_(when allow-continuous-feedback
              ;(println &quot;bad NARS&quot;)
              (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;)))
        (when (not= @updown-state &quot;above&quot;)
          (nars-input-narsese &quot;&lt;ballpos --&gt; [above]&gt;. :|:&quot;)
          #_(nars-input-narsese &quot;&lt;ballpos --&gt; [below]&gt;. :|: %0%&quot;)
          #_(nars-input-narsese &quot;&lt;ballpos --&gt; [equal]&gt;. :|: %0%&quot;)
          (reset! updown-state &quot;above&quot;)
          #_(when allow-continuous-feedback
              ;(println &quot;bad NARS&quot;)
              (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;))))))
  (let [kset-x (+ 0.6 (/ (Math/random) 2.0))
        kset-y (+ 0.6 (/ (Math/random) 2.0))
        state2 (assoc state
                 :ball-px #_(:ball-px state) (+ (:ball-px state) (* (:direction-x state) 1 1))
                 :ball-py #_(:ball-py state) (+ (:ball-py state) (* (:direction-y state) 1 1)))
        state3 (if (&gt;= (:ball-px state2)                     ;collided on right wall
                       fieldmax)
                 (assoc state2 :direction-x (- kset-x))
                 state2)
        state4 (if (&lt;= (:ball-px state3)                     ;collided on left wall!!
                       fieldmin)
                 (do
                   #_(nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;)
                   #_(nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;! :|:&quot;)
                   ;(println &quot;bad NARS&quot;)
                   (assoc state3 :direction-x kset-x))
                 state3)
        state5 (if (&gt;= (:ball-py state4)                     ;collided on upper wall
                       fieldmax)
                 (assoc state4 :direction-y (- kset-y))
                 state4)
        state6 (if (&lt;= (:ball-py state5)                     ;collided on down wall
                       fieldmin)
                 (assoc state5 :direction-y kset-y)
                 state5)
        state7 (if (and (&lt;= (:ball-px state6) 40)            ;got it
                        (&gt;= (:ball-py state6) @py)
                        (&lt;= (:ball-py state6) (+ @py barheight)))
                 (do
                   #_(nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %1.0;0.9%&quot;)
                   #_(nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;! :|:&quot;)
                   ;(println &quot;good NARS&quot;)
                   (assoc state6 :direction-x kset-x))
                 state6)]
    (when (&gt; @py (- fieldmax barheight (- fieldmin)))
      (reset! py (- fieldmax barheight (- fieldmin))))
    (when (&lt; @py fieldmin)
      (reset! py fieldmin))
    (assoc state7
      :ball-px (max fieldmin (min (:ball-px state7) fieldmax))
      :ball-py (max fieldmin (min (:ball-py state7) fieldmax))
      :iteration (inc (:iteration state7)))))</pre></td></tr><tr><td class="docs"><p>Draw the game</p>
</td><td class="codes"><pre class="brush: clojure">(defn draw-pong
  [state]
  (q/background (invert-comp 255))
  (q/stroke (invert-comp 0))
  (q/reset-matrix)
  (hnav/transform state)
  (q/fill (invert-comp 255))
  (q/rect fieldmin fieldmin fieldmax fieldmax)
  (q/fill 128)
  (q/rect 25 @py 10 barheight)
  (q/rect (:ball-px state) (:ball-py state) 10 10))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn -main []
  (q/defsketch pong
              :size [(hnav/width) (hnav/height)]
              :setup setup-pong
              :draw draw-pong
              :update update-pong
              :mouse-pressed (partial hnav/mouse-pressed [] {} false)
              :mouse-dragged hnav/mouse-dragged
              :mouse-wheel hnav/mouse-wheel
              :middleware [m/fun-mode]
              :features [:resizable]
              :title &quot;OpenNARS 2.0.0: Pong&quot;))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#examples.simplenario" name="examples.simplenario"><h1 class="project-name">examples.simplenario</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns examples.simplenario
  (:require [quil.core :as q]
            [quil.middleware :as m]
            [gui.hnav :as hnav]
            [gui.gui-utils :refer [invert-comp]]
            [narjure.global-atoms :refer :all]
            [narjure.core :as nar]
            [narjure.sensorimotor :refer :all])
  (:gen-class))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def px (atom 10))
(def py (atom 280))
(def direction (atom 0))
(def direction-x (atom 0))
(def barheight 125)
(def fieldmax 760)
(def fieldmax-x 76000)
(def fieldmin 20)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn with-print [x]
  #_(println (str x))
  x)</pre></td></tr><tr><td class="docs"><p>e &lt;-> <ballpos --> [equal]>
u &lt;-> ballpos --> [above]</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>Registers the operations</p>
</td><td class="codes"><pre class="brush: clojure">(defn setup-pong
  []
  (nars-input-narsese &quot;right! :|:&quot;)
  (q/frame-rate 80)
  (nars-register-operation 'self_op_up (fn [args operationgoal]
                                    (do
                                      (when (= @py (- fieldmax barheight (- fieldmin)))
                                        (reset! direction -1))
                                      (with-print (= @py (- fieldmax barheight (- fieldmin)))))))
  (nars-register-operation 'self_op_right (fn [args operationgoal]
                                      (do
                                        (when (= (:source operationgoal) :derived)
                                          #_(println &quot;system decided down&quot;))
                                        (reset! direction-x 1)
                                        true)))
  (nars-register-operation 'self_op_left (fn [args operationgoal]
                                            (do
                                              (when (= (:source operationgoal) :derived)
                                                #_(println &quot;system decided down&quot;))
                                              (reset! direction-x -1)
                                              true)))
  (merge hnav/states {:ball-px 80
                      :ball-py 750
                      :direction-x 1
                      :direction-y 1
                      :iteration 0}))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">&quot;
&lt;(&amp;/,(&amp;/,equal,i4,self_op_up),i4) =/&gt; right&gt;.
&lt;(&amp;/,(&amp;/,down,i4,self_op_right),i4) =/&gt; right&gt;.
&quot;</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def allow-continuous-feedback true)
(def updown-state (atom &quot;equal&quot;))</pre></td></tr><tr><td class="docs"><p>World state transition</p>
</td><td class="codes"><pre class="brush: clojure">(def ballpx-tmp (atom 10))
(def ballpy-tmp (atom 10))
(def pxmax (atom 100000))
(def collide (atom 0))
(defn update-pong
  [state]
  (reset! collide 0)
  (reset! pxmax 100000)
  (when (and (&lt; (Math/abs (- @px (:ball-px state))) 10)
             (&lt; (Math/abs (- (+ @py (/ barheight 2.0)) (:ball-py state))) (/ barheight 2.0)))
    #_(reset! direction-x -1)
    (reset! collide 1)
    (reset! pxmax @px))
  (reset! px (min (+ @direction-x @px)
                  @pxmax))
  (reset! direction-x (* 0.98 @direction-x))
  (reset! direction (+ 0.01 @direction))
  (reset! ballpx-tmp (:ball-px state))
  (reset! ballpy-tmp (:ball-py state))
  (reset! py (+ @py (* 3.0 @direction)))
  (when (&gt; @px (+ 50.0 @ballpx-tmp))
    (reset! ballpx-tmp (+ @px (+ 100.0 (* 30.0 (Math/random)))))
    (reset! ballpy-tmp (- fieldmax (* 200.0 (Math/random)))))
  (when (= (mod (:iteration state) 25) 0)
    #_(println (str &quot;above truth &quot; (vec (:truth (lense-max-statement-confidence-projected-to-now 'above :belief :event)))
                  &quot; below truth &quot; (vec (:truth (lense-max-statement-confidence-projected-to-now 'below :belief :event)))
                  &quot; equal truth &quot; (vec (:truth (lense-max-statement-confidence-projected-to-now 'equal :belief :event)))))
    (nars-input-narsese &quot;right! :|:&quot;))
  (when (= (mod (:iteration state) 200) 1)
    (println &quot;rand action&quot;)
    (nars-input-narsese (str (rand-nth [&quot;self_op_up! :|:&quot;
                                        &quot;self_op_left! :|:&quot;
                                        &quot;self_op_right! :|:&quot;
                                        #_&quot;&lt;(*,{SELF}) --&gt; op_stop&gt;! :|:&quot;]))))
  (when (and (= (mod (:iteration state) 60) 0)
             (= @collide 1))
    (nars-input-narsese &quot;collide. :|: %1.0;0.9%&quot;))
    ;also give info from time to time
  (when (and (not= @collide 1)
             (= (mod (:iteration state) 60) 0))                     ;1
    #_(nars-input-narsese (str &quot;&lt;{&quot; (int (* 100 (quot (:ball-py state) 100))) &quot;} --&gt; ballpos&gt;. :|:&quot; ))
    #_(nars-input-narsese (str &quot;&lt;{&quot; (int (* 100 (quot @py 100))) &quot;} --&gt; barpos&gt;. :|:&quot; ))
    (when (&gt; @direction-x 0.1)
      (nars-input-narsese &quot;right. :|: %1.0;0.9%&quot;))
    (if (and (&gt;= (:ball-py state) @py)
             (&lt;= (:ball-py state) (+ @py barheight)))
      (when true
        (nars-input-narsese &quot;nocoll. :|: %1.0;0.9%&quot;)
        (reset! updown-state &quot;equal&quot;)
        #_(when allow-continuous-feedback
            ;(println &quot;good NARS&quot;)
            (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %1.0;0.9%&quot;)))
      (if (&gt; (:ball-py state) @py)
        (when true
          (nars-input-narsese (str &quot;nocoll. :|:&quot;))
          (reset! updown-state &quot;below&quot;)
          #_(when allow-continuous-feedback
              ;(println &quot;bad NARS&quot;)
              (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;)))
        (when true
          (nars-input-narsese (str &quot;nocoll. :|:&quot;))
          (reset! updown-state &quot;above&quot;)
          #_(when allow-continuous-feedback
              ;(println &quot;bad NARS&quot;)
              (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;))))))
  (when (and (= (mod (:iteration state) 1) 0)
             (not= @collide 1))                    ;1
    #_(nars-input-narsese (str &quot;&lt;{&quot; (int (* 100 (quot (:ball-py state) 100))) &quot;} --&gt; ballpos&gt;. :|:&quot; ))
    #_(nars-input-narsese (str &quot;&lt;{&quot; (int (* 100 (quot @py 100))) &quot;} --&gt; barpos&gt;. :|:&quot; ))
    (if (and (&gt;= (:ball-py state) @py)
             (&lt;= (:ball-py state) (+ @py barheight)))
      (when (not= @updown-state &quot;equal&quot;)
        (nars-input-narsese &quot;nocoll. :|: %1.0;0.9%&quot;)
        #_(nars-input-narsese &quot;above. :|: %0%&quot;)
        #_(nars-input-narsese &quot;below. :|: %0%&quot;)
        (reset! updown-state &quot;equal&quot;)
        #_(when allow-continuous-feedback
            ;(println &quot;good NARS&quot;)
            (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %1.0;0.9%&quot;)))
      (if (&gt; (:ball-py state) @py)
        (when (not= @updown-state &quot;below&quot;)
          (nars-input-narsese &quot;nocoll. :|:&quot;)
          #_(nars-input-narsese &quot;above. :|: %0%&quot;)
          #_ (nars-input-narsese &quot;equal. :|: %0%&quot;)
          (reset! updown-state &quot;below&quot;)
          #_(when allow-continuous-feedback
              ;(println &quot;bad NARS&quot;)
              (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;)))
        (when (not= @updown-state &quot;above&quot;)
          (nars-input-narsese &quot;nocoll. :|:&quot;)
          #_(nars-input-narsese &quot;below. :|: %0%&quot;)
          #_(nars-input-narsese &quot;equal. :|: %0%&quot;)
          (reset! updown-state &quot;above&quot;)
          #_(when allow-continuous-feedback
              ;(println &quot;bad NARS&quot;)
              (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;))))))
  (let [kset-x (+ 0.6 (/ (Math/random) 2.0))
        kset-y (+ 0.6 (/ (Math/random) 2.0))
        state2 (assoc state
                 :ball-px @ballpx-tmp
                 :ball-py @ballpy-tmp)
        state3 state2
        state4 state3
        state5 (if (&gt;= (:ball-py state4)                     ;collided on upper wall
                       fieldmax)
                 (assoc state4 :direction-y (- kset-y))
                 state4)
        state6 (if (&lt;= (:ball-py state5)                     ;collided on down wall
                       fieldmin)
                 (assoc state5 :direction-y kset-y)
                 state5)
        state7 (if (and (&lt;= (:ball-px state6) 40)            ;got it
                        (&gt;= (:ball-py state6) @py)
                        (&lt;= (:ball-py state6) (+ @py barheight)))
                 (do
                   #_(nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %1.0;0.9%&quot;)
                   #_(nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;! :|:&quot;)
                   ;(println &quot;good NARS&quot;)
                   (assoc state6 :direction-x kset-x))
                 state6)]
    (when (&gt; @py (- fieldmax barheight (- fieldmin)))
      (reset! py (- fieldmax barheight (- fieldmin))))
    (when (&lt; @py fieldmin)
      (reset! py fieldmin))
    (assoc state7
      :ball-px (max fieldmin (min (:ball-px state7) fieldmax-x))
      :ball-py (max fieldmin (min (:ball-py state7) fieldmax))
      :iteration (inc (:iteration state7)))))</pre></td></tr><tr><td class="docs"><p>Draw the game</p>
</td><td class="codes"><pre class="brush: clojure">(defn draw-pong
  [state]
  (q/background (invert-comp 255))
  (q/stroke (invert-comp 0))
  (q/reset-matrix)
  (hnav/transform state)
  (q/fill (invert-comp 255))
  (q/rect -1000 fieldmin fieldmax-x fieldmax)
  (q/fill 128)
  (q/rect @px @py 10 barheight)
  (q/rect (:ball-px state) (:ball-py state) 10 10))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn -main []
  (q/defsketch pong
              :size [(hnav/width) (hnav/height)]
              :setup setup-pong
              :draw draw-pong
              :update update-pong
              :mouse-pressed (partial hnav/mouse-pressed [] {} false)
              :mouse-dragged hnav/mouse-dragged
              :mouse-wheel hnav/mouse-wheel
              :middleware [m/fun-mode]
              :features [:resizable]
              :title &quot;OpenNARS 2.0.0: Pong&quot;))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#examples.simplepong" name="examples.simplepong"><h1 class="project-name">examples.simplepong</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns examples.simplepong
  (:require [quil.core :as q]
            [quil.middleware :as m]
            [gui.hnav :as hnav]
            [gui.gui-utils :refer [invert-comp]]
            [narjure.global-atoms :refer :all]
            [narjure.core :as nar]
            [narjure.sensorimotor :refer :all])
  (:gen-class))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def py (atom 280))
(def direction (atom 0))
(def barheight 125)
(def fieldmax 760)
(def fieldmin 20)</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn with-print [x]
  #_(println (str x))
  x)</pre></td></tr><tr><td class="docs"><p>e &lt;-> <ballpos --> [equal]>
u &lt;-> ballpos --> [above]</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>Registers the operations</p>
</td><td class="codes"><pre class="brush: clojure">(defn setup-pong
  []
  (nars-input-narsese &quot;equal! :|:&quot;)
  (q/frame-rate 100)
  (nars-register-operation 'self_op_up (fn [args operationgoal]
                                    (do
                                      (when (= (:source operationgoal) :derived)
                                        #_(println &quot;system decided up&quot;))
                                      (reset! direction -1)
                                      (with-print (not= @py fieldmin)))))
  (nars-register-operation 'self_op_down (fn [args operationgoal]
                                      (do
                                        (when (= (:source operationgoal) :derived)
                                          #_(println &quot;system decided down&quot;))
                                        (reset! direction 1)
                                        (with-print (not= @py (- fieldmax barheight (- fieldmin)))))))
  (merge hnav/states {:ball-px 380
                      :ball-py 400
                      :direction-x 1
                      :direction-y 1
                      :iteration 0}))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">&quot;
&lt;(&amp;/,(&amp;/,below,i4,self_op_down),i4) =/&gt; equal&gt;.
&lt;(&amp;/,(&amp;/,above,i4,self_op_up),i4) =/&gt; equal&gt;.
&quot;</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(def allow-continuous-feedback true)
(def updown-state (atom &quot;equal&quot;))</pre></td></tr><tr><td class="docs"><p>World state transition</p>
</td><td class="codes"><pre class="brush: clojure">(defn update-pong
  [state]
  (when (= @direction -1)
    (reset! py (+ @py -3)))
  (when (= @direction 1)
    (reset! py (+ @py 3)))
  (when (= (mod (:iteration state) 25) 0)
    #_(println (str &quot;above truth &quot; (vec (:truth (lense-max-statement-confidence-projected-to-now 'above :belief :event)))
                  &quot; below truth &quot; (vec (:truth (lense-max-statement-confidence-projected-to-now 'below :belief :event)))
                  &quot; equal truth &quot; (vec (:truth (lense-max-statement-confidence-projected-to-now 'equal :belief :event)))))
    (nars-input-narsese &quot;equal! :|:&quot;))
  (when (= (mod (:iteration state) 125) 1)
    (println &quot;rand action&quot;)
    (nars-input-narsese (str (rand-nth [&quot;self_op_up! :|:&quot;
                                        &quot;self_op_down! :|:&quot;
                                        #_&quot;&lt;(*,{SELF}) --&gt; op_stop&gt;! :|:&quot;]))))
  ;also give info from time to time
  #_(when (= (mod (:iteration state) 80) 0)                    ;1
    #_(nars-input-narsese (str &quot;&lt;{&quot; (int (* 100 (quot (:ball-py state) 100))) &quot;} --&gt; ballpos&gt;. :|:&quot; ))
    #_(nars-input-narsese (str &quot;&lt;{&quot; (int (* 100 (quot @py 100))) &quot;} --&gt; barpos&gt;. :|:&quot; ))
    (if (and (&gt;= (:ball-py state) @py)
             (&lt;= (:ball-py state) (+ @py barheight)))
      (when true
        (nars-input-narsese &quot;&lt;ballpos --&gt; [equal]&gt;. :|: %1.0;0.9%&quot;)
        (reset! updown-state &quot;equal&quot;)
        #_(when allow-continuous-feedback
            ;(println &quot;good NARS&quot;)
            (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %1.0;0.9%&quot;)))
      (if (&gt; (:ball-py state) @py)
        (when true
          (nars-input-narsese (str &quot;&lt;ballpos --&gt; [below]&gt;. :|:&quot;))
          (reset! updown-state &quot;below&quot;)
          #_(when allow-continuous-feedback
              ;(println &quot;bad NARS&quot;)
              (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;)))
        (when true
          (nars-input-narsese (str &quot;&lt;ballpos --&gt; [above]&gt;. :|:&quot;))
          (reset! updown-state &quot;above&quot;)
          #_(when allow-continuous-feedback
              ;(println &quot;bad NARS&quot;)
              (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;))))))
  (when (= (mod (:iteration state) 1) 0)                    ;1
    #_(nars-input-narsese (str &quot;&lt;{&quot; (int (* 100 (quot (:ball-py state) 100))) &quot;} --&gt; ballpos&gt;. :|:&quot; ))
    #_(nars-input-narsese (str &quot;&lt;{&quot; (int (* 100 (quot @py 100))) &quot;} --&gt; barpos&gt;. :|:&quot; ))
    (if (and (&gt;= (:ball-py state) @py)
             (&lt;= (:ball-py state) (+ @py barheight)))
      (when (not= @updown-state &quot;equal&quot;)
        (nars-input-narsese &quot;equal. :|: %1.0;0.9%&quot;)
        #_(nars-input-narsese &quot;above. :|: %0%&quot;)
        #_(nars-input-narsese &quot;below. :|: %0%&quot;)
        (reset! updown-state &quot;equal&quot;)
        #_(when allow-continuous-feedback
            ;(println &quot;good NARS&quot;)
            (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %1.0;0.9%&quot;)))
      (if (&gt; (:ball-py state) @py)
        (when (not= @updown-state &quot;below&quot;)
          (nars-input-narsese &quot;below. :|:&quot;)
          #_(nars-input-narsese &quot;above. :|: %0%&quot;)
          #_ (nars-input-narsese &quot;equal. :|: %0%&quot;)
          (reset! updown-state &quot;below&quot;)
          #_(when allow-continuous-feedback
              ;(println &quot;bad NARS&quot;)
              (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;)))
        (when (not= @updown-state &quot;above&quot;)
          (nars-input-narsese &quot;above. :|:&quot;)
          #_(nars-input-narsese &quot;below. :|: %0%&quot;)
          #_(nars-input-narsese &quot;equal. :|: %0%&quot;)
          (reset! updown-state &quot;above&quot;)
          #_(when allow-continuous-feedback
              ;(println &quot;bad NARS&quot;)
              (nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;))))))
  (let [kset-x (+ 0.6 (/ (Math/random) 2.0))
        kset-y (+ 0.6 (/ (Math/random) 2.0))
        state2 (assoc state
                 :ball-px #_(:ball-px state) (+ (:ball-px state) (* (:direction-x state) 1 1))
                 :ball-py #_(:ball-py state) (+ (:ball-py state) (* (:direction-y state) 1 1)))
        state3 (if (&gt;= (:ball-px state2)                     ;collided on right wall
                       fieldmax)
                 (assoc state2 :direction-x (- kset-x))
                 state2)
        state4 (if (&lt;= (:ball-px state3)                     ;collided on left wall!!
                       fieldmin)
                 (do
                   #_(nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %0.0;0.9%&quot;)
                   #_(nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;! :|:&quot;)
                   ;(println &quot;bad NARS&quot;)
                   (assoc state3 :direction-x kset-x))
                 state3)
        state5 (if (&gt;= (:ball-py state4)                     ;collided on upper wall
                       fieldmax)
                 (assoc state4 :direction-y (- kset-y))
                 state4)
        state6 (if (&lt;= (:ball-py state5)                     ;collided on down wall
                       fieldmin)
                 (assoc state5 :direction-y kset-y)
                 state5)
        state7 (if (and (&lt;= (:ball-px state6) 40)            ;got it
                        (&gt;= (:ball-py state6) @py)
                        (&lt;= (:ball-py state6) (+ @py barheight)))
                 (do
                   #_(nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;. :|: %1.0;0.9%&quot;)
                   #_(nars-input-narsese &quot;&lt;{SELF} --&gt; [good]&gt;! :|:&quot;)
                   ;(println &quot;good NARS&quot;)
                   (assoc state6 :direction-x kset-x))
                 state6)]
    (when (&gt; @py (- fieldmax barheight (- fieldmin)))
      (reset! py (- fieldmax barheight (- fieldmin))))
    (when (&lt; @py fieldmin)
      (reset! py fieldmin))
    (assoc state7
      :ball-px (max fieldmin (min (:ball-px state7) fieldmax))
      :ball-py (max fieldmin (min (:ball-py state7) fieldmax))
      :iteration (inc (:iteration state7)))))</pre></td></tr><tr><td class="docs"><p>Draw the game</p>
</td><td class="codes"><pre class="brush: clojure">(defn draw-pong
  [state]
  (q/background (invert-comp 255))
  (q/stroke (invert-comp 0))
  (q/reset-matrix)
  (hnav/transform state)
  (q/fill (invert-comp 255))
  (q/rect fieldmin fieldmin fieldmax fieldmax)
  (q/fill 128)
  (q/rect 25 @py 10 barheight)
  (q/rect (:ball-px state) (:ball-py state) 10 10))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn -main []
  (q/defsketch pong
              :size [(hnav/width) (hnav/height)]
              :setup setup-pong
              :draw draw-pong
              :update update-pong
              :mouse-pressed (partial hnav/mouse-pressed [] {} false)
              :mouse-dragged hnav/mouse-dragged
              :mouse-wheel hnav/mouse-wheel
              :middleware [m/fun-mode]
              :features [:resizable]
              :title &quot;OpenNARS 2.0.0: Pong&quot;))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr></table><div class="footer">Generated by <a href="https://github.com/gdeer81/marginalia">Marginalia</a>.&nbsp;&nbsp;Syntax highlighting provided by Alex Gorbatchev's <a href="http://alexgorbatchev.com/SyntaxHighlighter/">SyntaxHighlighter</a><div id="floating-toc"><ul><li class="floating-toc-li" id="floating-toc_nal.core">nal.core</li><li class="floating-toc-li" id="floating-toc_nal.deriver.backward-rules">nal.deriver.backward-rules</li><li class="floating-toc-li" id="floating-toc_nal.deriver.key-path">nal.deriver.key-path</li><li class="floating-toc-li" id="floating-toc_nal.deriver.list-expansion">nal.deriver.list-expansion</li><li class="floating-toc-li" id="floating-toc_nal.deriver.matching">nal.deriver.matching</li><li class="floating-toc-li" id="floating-toc_nal.deriver.normalization">nal.deriver.normalization</li><li class="floating-toc-li" id="floating-toc_nal.deriver.preconditions">nal.deriver.preconditions</li><li class="floating-toc-li" id="floating-toc_nal.deriver.premises-swapping">nal.deriver.premises-swapping</li><li class="floating-toc-li" id="floating-toc_nal.deriver.projection-eternalization">nal.deriver.projection-eternalization</li><li class="floating-toc-li" id="floating-toc_nal.deriver.rules">nal.deriver.rules</li><li class="floating-toc-li" id="floating-toc_nal.deriver.set-functions">nal.deriver.set-functions</li><li class="floating-toc-li" id="floating-toc_nal.deriver.substitution">nal.deriver.substitution</li><li class="floating-toc-li" id="floating-toc_nal.deriver.terms-permutation">nal.deriver.terms-permutation</li><li class="floating-toc-li" id="floating-toc_nal.deriver.truth">nal.deriver.truth</li><li class="floating-toc-li" id="floating-toc_nal.deriver.utils">nal.deriver.utils</li><li class="floating-toc-li" id="floating-toc_nal.deriver">nal.deriver</li><li class="floating-toc-li" id="floating-toc_nal.reader">nal.reader</li><li class="floating-toc-li" id="floating-toc_nal.rules">nal.rules</li><li class="floating-toc-li" id="floating-toc_nal.term_utils">nal.term_utils</li><li class="floating-toc-li" id="floating-toc_nal.test_utils">nal.test_utils</li><li class="floating-toc-li" id="floating-toc_narjure.actor.utils">narjure.actor.utils</li><li class="floating-toc-li" id="floating-toc_narjure.bag">narjure.bag</li><li class="floating-toc-li" id="floating-toc_narjure.budget-functions">narjure.budget-functions</li><li class="floating-toc-li" id="floating-toc_narjure.control-utils">narjure.control-utils</li><li class="floating-toc-li" id="floating-toc_narjure.core">narjure.core</li><li class="floating-toc-li" id="floating-toc_narjure.debug-util">narjure.debug-util</li><li class="floating-toc-li" id="floating-toc_narjure.defaults">narjure.defaults</li><li class="floating-toc-li" id="floating-toc_narjure.general-inference.concept-selector">narjure.general-inference.concept-selector</li><li class="floating-toc-li" id="floating-toc_narjure.general-inference.general-inferencer">narjure.general-inference.general-inferencer</li><li class="floating-toc-li" id="floating-toc_narjure.general-inference.inference-request-router">narjure.general-inference.inference-request-router</li><li class="floating-toc-li" id="floating-toc_narjure.global-atoms">narjure.global-atoms</li><li class="floating-toc-li" id="floating-toc_narjure.memory-management.concept">narjure.memory-management.concept</li><li class="floating-toc-li" id="floating-toc_narjure.memory-management.concept-manager">narjure.memory-management.concept-manager</li><li class="floating-toc-li" id="floating-toc_narjure.memory-management.concept-utils">narjure.memory-management.concept-utils</li><li class="floating-toc-li" id="floating-toc_narjure.memory-management.forgettor">narjure.memory-management.forgettor</li><li class="floating-toc-li" id="floating-toc_narjure.memory-management.local-inference.belief-processor">narjure.memory-management.local-inference.belief-processor</li><li class="floating-toc-li" id="floating-toc_narjure.memory-management.local-inference.goal-processor">narjure.memory-management.local-inference.goal-processor</li><li class="floating-toc-li" id="floating-toc_narjure.memory-management.local-inference.local-inference-utils">narjure.memory-management.local-inference.local-inference-utils</li><li class="floating-toc-li" id="floating-toc_narjure.memory-management.local-inference.question-processor">narjure.memory-management.local-inference.question-processor</li><li class="floating-toc-li" id="floating-toc_narjure.memory-management.local-inference.quest-processor">narjure.memory-management.local-inference.quest-processor</li><li class="floating-toc-li" id="floating-toc_narjure.memory-management.task-dispatcher">narjure.memory-management.task-dispatcher</li><li class="floating-toc-li" id="floating-toc_narjure.memory-management.termlink-utils">narjure.memory-management.termlink-utils</li><li class="floating-toc-li" id="floating-toc_narjure.narsese">narjure.narsese</li><li class="floating-toc-li" id="floating-toc_narjure.perception-action.derived-load-reducer">narjure.perception-action.derived-load-reducer</li><li class="floating-toc-li" id="floating-toc_narjure.perception-action.operator-executor">narjure.perception-action.operator-executor</li><li class="floating-toc-li" id="floating-toc_narjure.perception-action.sentence-parser">narjure.perception-action.sentence-parser</li><li class="floating-toc-li" id="floating-toc_narjure.perception-action.task-creator">narjure.perception-action.task-creator</li><li class="floating-toc-li" id="floating-toc_narjure.projection-utils">narjure.projection-utils</li><li class="floating-toc-li" id="floating-toc_narjure.repl">narjure.repl</li><li class="floating-toc-li" id="floating-toc_narjure.runtime-utils">narjure.runtime-utils</li><li class="floating-toc-li" id="floating-toc_narjure.sensorimotor">narjure.sensorimotor</li><li class="floating-toc-li" id="floating-toc_gui.actors">gui.actors</li><li class="floating-toc-li" id="floating-toc_gui.globals">gui.globals</li><li class="floating-toc-li" id="floating-toc_gui.gui">gui.gui</li><li class="floating-toc-li" id="floating-toc_gui.gui-utils">gui.gui-utils</li><li class="floating-toc-li" id="floating-toc_gui.hnav">gui.hnav</li><li class="floating-toc-li" id="floating-toc_gui.hud">gui.hud</li><li class="floating-toc-li" id="floating-toc_gui.lense">gui.lense</li><li class="floating-toc-li" id="floating-toc_examples.ircbot">examples.ircbot</li><li class="floating-toc-li" id="floating-toc_examples.pong">examples.pong</li><li class="floating-toc-li" id="floating-toc_examples.simplenario">examples.simplenario</li><li class="floating-toc-li" id="floating-toc_examples.simplepong">examples.simplepong</li></ul></div></div><script type="text/javascript">SyntaxHighlighter.defaults['gutter'] = false;
SyntaxHighlighter.all();

// hackity hack
$(window).load(function() {
    var ft = $("#floating-toc");
    var ul = ft.find('ul');
    var lis = ft.find('li');
    var liHeight = $(lis.first()).height();

    ul.css('margin', '0px');
    ft.css('height', liHeight + 'px');

    showNs = function(ns) {
        var index = 0;

        for(i in nsPositions.nss) {
            if(ns == nsPositions.nss[i]) index = i;
        }

        if(index != lastNsIndex) {
            lastNsIndex = index;
            ul.animate({marginTop: (-1 * liHeight * index) + 'px'},
               300);
        }

    }

    var calcNsPositions = function() {
        var hheight = $('.docs-header').first().height();
        var nss = [];
        var anchors = [];
        var positions = [];
        $.each(lis, function(i, el) {
            var ns = $(el).attr('id').split('_')[1];
            nss.push(ns);
            var a = $("a[name='"+ns+"']");
            anchors.push(a);
            positions.push(a.offset().top - hheight);
            // console.log(a.offset().top)
        });

        return {nss: nss, positions: positions};
    }

    var nsPositions = calcNsPositions();
    // console.log(nsPositions)
    var lastNsIndex = -1;
    var $window = $(window);

    var currentSection = function(nsp) {
        var ps = nsp.positions;
        var scroll = $window.scrollTop();
        var nsIndex = -1;

        for(var i = 0, length = ps.length; i < length; i++) {
            if(ps[i] >= scroll) {
                nsIndex = i-1;
                break;
            }
        }

        if(nsIndex == -1) {
             if(scroll >= ps[0]) {
                 nsIndex = ps.length - 1;
             } else {
                 nsIndex = 0;
             }
        }

        return nsp.nss[nsIndex];
    }

    $(window).scroll(function(e) {
        showNs(currentSection(nsPositions));
    });
});
</script></body></html>